Private
Public Access
1
0

Merge branch 'release/v8.00'

This commit is contained in:
Sander Roosendaal
2018-10-16 18:55:53 +02:00
166 changed files with 11730 additions and 10864 deletions
+3
View File
@@ -266,7 +266,10 @@ def summaryfromsplitdata(splitdata,data,filename,sep='|'):
idist = interval['distance'] idist = interval['distance']
itime = interval['time']/10. itime = interval['time']/10.
ipace = 500.*itime/idist ipace = 500.*itime/idist
try:
ispm = interval['stroke_rate'] ispm = interval['stroke_rate']
except KeyError:
ispm = 0
try: try:
irest_time = interval['rest_time']/10. irest_time = interval['rest_time']/10.
except KeyError: except KeyError:
+2 -1
View File
@@ -241,6 +241,7 @@ def add_c2_stroke_data_db(strokedata,workoutid,starttimeunix,csvfilename,
hr = strokedata.ix[:,'hr'] hr = strokedata.ix[:,'hr']
except KeyError: except KeyError:
hr = 0*spm hr = 0*spm
pace = strokedata.ix[:,'p']/10. pace = strokedata.ix[:,'p']/10.
pace = np.clip(pace,0,1e4) pace = np.clip(pace,0,1e4)
pace = pace.replace(0,300) pace = pace.replace(0,300)
@@ -1241,7 +1242,7 @@ def dataprep(rowdatadf,id=0,bands=True,barchart=True,otwpower=True,
with engine.connect() as conn, conn.begin(): with engine.connect() as conn, conn.begin():
try: try:
data.to_sql('strokedata',engine,if_exists='append',index=False) data.to_sql('strokedata',engine,if_exists='append',index=False)
except OperationalError: except:
data.drop(columns=['rhythm'],inplace=True) data.drop(columns=['rhythm'],inplace=True)
data.to_sql('strokedata',engine,if_exists='append',index=False) data.to_sql('strokedata',engine,if_exists='append',index=False)
+71 -1
View File
@@ -7,12 +7,14 @@ from django.contrib.auth.models import User
from django.contrib.admin.widgets import AdminDateWidget from django.contrib.admin.widgets import AdminDateWidget
from django.forms.extras.widgets import SelectDateWidget from django.forms.extras.widgets import SelectDateWidget
from django.utils import timezone,translation from django.utils import timezone,translation
from django.forms import ModelForm from django.forms import ModelForm, Select
import dataprep import dataprep
import types import types
import datetime import datetime
from django.forms import formset_factory from django.forms import formset_factory
from utils import landingpages from utils import landingpages
from metrics import axes
# login form # login form
class LoginForm(forms.Form): class LoginForm(forms.Form):
@@ -29,6 +31,7 @@ class EmailForm(forms.Form):
message = forms.CharField() message = forms.CharField()
# Upload the CrewNerd Summary CSV # Upload the CrewNerd Summary CSV
class CNsummaryForm(forms.Form): class CNsummaryForm(forms.Form):
file = forms.FileField(required=True,validators=[must_be_csv]) file = forms.FileField(required=True,validators=[must_be_csv])
@@ -919,3 +922,70 @@ class VirtualRaceSelectForm(forms.Form):
self.fields['country'] = forms.ChoiceField( self.fields['country'] = forms.ChoiceField(
choices = get_countries(),initial='All' choices = get_countries(),initial='All'
) )
class FlexOptionsForm(forms.Form):
includereststrokes = forms.BooleanField(initial=True, required = False,
label='Include Rest Strokes')
plotchoices = (
('line','Line Plot'),
('scatter','Scatter Plot'),
)
plottype = forms.ChoiceField(choices=plotchoices,initial='scatter',
label='Chart Type')
class FlexAxesForm(forms.Form):
axchoices = (
(ax[0],ax[1]) for ax in axes if ax[0] not in ['cumdist','None']
)
yaxchoices = (
(ax[0], ax[1]) for ax in axes if ax[0] not in ['cumdist','distance','time']
)
yaxchoices2 = (
(ax[0], ax[1]) for ax in axes if ax[0] not in ['cumdist','distance','time']
)
xaxis = forms.ChoiceField(
choices=axchoices,label='X-Axis',required=True)
yaxis1 = forms.ChoiceField(
choices=yaxchoices,label='Left Axis',required=True)
yaxis2 = forms.ChoiceField(
choices=yaxchoices2,label='Right Axis',required=True)
def __init__(self,request,*args,**kwargs):
super(FlexAxesForm, self).__init__(*args, **kwargs)
rower = Rower.objects.get(user=request.user)
axchoicespro = (
('',ax[1]) if ax[4] == 'pro' and ax[0] else (ax[0],ax[1]) for ax in axes
)
axchoicesbasicx = []
axchoicesbasicy = []
for ax in axes:
if ax[4] != 'pro' and ax[0] != 'cumdist':
if ax[0] != 'None':
axchoicesbasicx.insert(0,(ax[0],ax[1]))
if ax[0] not in ['cumdist','distance','time']:
axchoicesbasicy.insert(0,(ax[0],ax[1]))
else:
if ax[0] != 'None':
axchoicesbasicx.insert(0,('None',ax[1]+' (PRO)'))
if ax[0] not in ['cumdist','distance','time']:
axchoicesbasicy.insert(0,('None',ax[1]+' (PRO)'))
if rower.rowerplan == 'basic':
self.fields['xaxis'].choices = axchoicesbasicx
self.fields['yaxis1'].choices = axchoicesbasicy
self.fields['yaxis2'].choices = axchoicesbasicy
+40 -7
View File
@@ -181,10 +181,11 @@ def interactive_boxchart(datadf,fieldname,extratitle=''):
tools=TOOLS, tools=TOOLS,
toolbar_location="above", toolbar_location="above",
toolbar_sticky=False, toolbar_sticky=False,
x_mapper_type='datetime') x_mapper_type='datetime',plot_width=920)
yrange1 = Range1d(start=yaxminima[fieldname],end=yaxmaxima[fieldname]) yrange1 = Range1d(start=yaxminima[fieldname],end=yaxmaxima[fieldname])
plot.y_range = yrange1 plot.y_range = yrange1
plot.sizing_mode = 'scale_width'
plot.xaxis.axis_label = 'Date' plot.xaxis.axis_label = 'Date'
plot.yaxis.axis_label = axlabels[fieldname] plot.yaxis.axis_label = axlabels[fieldname]
@@ -299,6 +300,7 @@ def interactive_activitychart(workouts,startdate,enddate,stack='type'):
toolbar_location = None, toolbar_location = None,
) )
for legend in p.legend: for legend in p.legend:
new_items = [] new_items = []
for legend_item in legend.items: for legend_item in legend.items:
@@ -311,6 +313,7 @@ def interactive_activitychart(workouts,startdate,enddate,stack='type'):
p.legend.location = "top_left" p.legend.location = "top_left"
p.legend.background_fill_alpha = 0.7 p.legend.background_fill_alpha = 0.7
p.sizing_mode = 'scale_width'
p.yaxis.axis_label = 'Minutes' p.yaxis.axis_label = 'Minutes'
@@ -411,6 +414,7 @@ def interactive_forcecurve(theworkouts,workstrokesonly=False):
# add watermark # add watermark
plot.extra_y_ranges = {"watermark": watermarkrange} plot.extra_y_ranges = {"watermark": watermarkrange}
plot.extra_x_ranges = {"watermark": watermarkrange} plot.extra_x_ranges = {"watermark": watermarkrange}
plot.sizing_mode = 'scale_width'
plot.image_url([watermarkurl],watermarkx,watermarky, plot.image_url([watermarkurl],watermarkx,watermarky,
watermarkw,watermarkh, watermarkw,watermarkh,
@@ -625,6 +629,8 @@ def interactive_forcecurve(theworkouts,workstrokesonly=False):
), ),
plot]) plot])
layout.sizing_mode = 'scale_width'
script, div = components(layout) script, div = components(layout)
js_resources = INLINE.render_js() js_resources = INLINE.render_js()
css_resources = INLINE.render_css() css_resources = INLINE.render_css()
@@ -748,9 +754,10 @@ def fitnessmetric_chart(fitnessmetrics,user,workoutmode='rower'):
) )
plot.xaxis.major_label_orientation = pi/4 plot.xaxis.major_label_orientation = pi/4
plot.sizing_mode = 'scale_width'
plot.y_range = Range1d(0,1.5*max(power4min)) plot.y_range = Range1d(0,1.5*max(power4min))
plot.title.text = 'Power levels from workouts '+user.first_name plot.title.text = 'Power levels ('+workoutmode+') from workouts '+user.first_name
hover = plot.select(dict(type=HoverTool)) hover = plot.select(dict(type=HoverTool))
@@ -834,6 +841,7 @@ def interactive_histoall(theworkouts):
plot.yaxis.axis_label = "% of strokes" plot.yaxis.axis_label = "% of strokes"
plot.y_range = Range1d(0,1.05*max(hist_norm)) plot.y_range = Range1d(0,1.05*max(hist_norm))
hover = plot.select(dict(type=HoverTool)) hover = plot.select(dict(type=HoverTool))
hover.tooltips = OrderedDict([ hover.tooltips = OrderedDict([
@@ -850,6 +858,7 @@ def interactive_histoall(theworkouts):
plot.add_layout(LinearAxis(y_range_name="fraction", plot.add_layout(LinearAxis(y_range_name="fraction",
axis_label="Cumulative % of strokes"),'right') axis_label="Cumulative % of strokes"),'right')
plot.sizing_mode = 'scale_width'
script, div = components(plot) script, div = components(plot)
return [script,div] return [script,div]
@@ -985,7 +994,7 @@ def course_map(course):
) )
div = """ div = """
<div id="map_canvas" style="width: 100%; height: 400px;"><p>&nbsp;</p></div> <div id="map_canvas" style="width: 100%; height: 400px; margin:0; padding:0;grid-gap:0;"></div>
""" """
return script,div return script,div
@@ -1483,7 +1492,11 @@ def interactive_agegroupcpchart(age,normalized=False):
x_axis_type = 'log' x_axis_type = 'log'
y_axis_type = 'linear' y_axis_type = 'linear'
plot = Figure(plot_width=900,x_axis_type=x_axis_type) TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,resize,crosshair'
plot = Figure(plot_width=900,x_axis_type=x_axis_type,
tools=TOOLS)
plot.sizing_mode = 'scale_width'
plot.line('duration','fitpowerfh',source=source, plot.line('duration','fitpowerfh',source=source,
legend='Female HW',color='blue') legend='Female HW',color='blue')
@@ -1574,6 +1587,7 @@ def interactive_otwcpchart(powerdf,promember=0,rowername=""):
# add watermark # add watermark
plot.extra_y_ranges = {"watermark": watermarkrange} plot.extra_y_ranges = {"watermark": watermarkrange}
plot.sizing_mode = 'scale_width'
plot.image_url([watermarkurl],1.8*max(thesecs),watermarky, plot.image_url([watermarkurl],1.8*max(thesecs),watermarky,
watermarkw,watermarkh, watermarkw,watermarkh,
@@ -1664,6 +1678,7 @@ def interactive_agegroup_plot(df,distance=2000,duration=None,
TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,resize,crosshair' TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,resize,crosshair'
plot = Figure(tools=TOOLS,plot_width=900) plot = Figure(tools=TOOLS,plot_width=900)
plot.sizing_mode='scale_width'
plot.circle('age','power',source=source,fill_color='red',size=15, plot.circle('age','power',source=source,fill_color='red',size=15,
legend='World Record') legend='World Record')
@@ -1861,6 +1876,7 @@ def interactive_cpchart(rower,thedistances,thesecs,theavpower,
# add watermark # add watermark
plot.extra_y_ranges = {"watermark": watermarkrange} plot.extra_y_ranges = {"watermark": watermarkrange}
plot.sizing_mode = 'scale_width'
plot.image_url([watermarkurl],1.8*max(thesecs),watermarky, plot.image_url([watermarkurl],1.8*max(thesecs),watermarky,
watermarkw,watermarkh, watermarkw,watermarkh,
@@ -2043,6 +2059,7 @@ def interactive_windchart(id=0,promember=0):
plot.xaxis.axis_label = "Distance (m)" plot.xaxis.axis_label = "Distance (m)"
plot.yaxis.axis_label = "Wind Speed (m/s)" plot.yaxis.axis_label = "Wind Speed (m/s)"
plot.y_range = Range1d(-7,7) plot.y_range = Range1d(-7,7)
plot.sizing_mode = 'scale_width'
plot.extra_y_ranges = {"winddirection": Range1d(start=0,end=360)} plot.extra_y_ranges = {"winddirection": Range1d(start=0,end=360)}
@@ -2110,6 +2127,7 @@ def interactive_streamchart(id=0,promember=0):
plot.xaxis.axis_label = "Distance (m)" plot.xaxis.axis_label = "Distance (m)"
plot.yaxis.axis_label = "River Current (m/s)" plot.yaxis.axis_label = "River Current (m/s)"
plot.y_range = Range1d(-2,2) plot.y_range = Range1d(-2,2)
plot.sizing_mode = 'scale_width'
script, div = components(plot) script, div = components(plot)
@@ -2179,6 +2197,7 @@ def interactive_chart(id=0,promember=0,intervaldata = {}):
plot.line('time','pace',source=source,legend="Pace",name="pace") plot.line('time','pace',source=source,legend="Pace",name="pace")
plot.title.text = row.name plot.title.text = row.name
plot.title.text_font_size=value("1.0em") plot.title.text_font_size=value("1.0em")
plot.sizing_mode = 'scale_width'
plot.xaxis.axis_label = "Time" plot.xaxis.axis_label = "Time"
plot.yaxis.axis_label = "Pace (/500m)" plot.yaxis.axis_label = "Pace (/500m)"
plot.xaxis[0].formatter = DatetimeTickFormatter( plot.xaxis[0].formatter = DatetimeTickFormatter(
@@ -2348,7 +2367,7 @@ def interactive_multiflex(datadf,xparam,yparam,groupby,extratitle='',
plot = Figure(x_axis_type=x_axis_type,y_axis_type=y_axis_type, plot = Figure(x_axis_type=x_axis_type,y_axis_type=y_axis_type,
tools=TOOLS, tools=TOOLS,
toolbar_location="above", toolbar_location="above",
toolbar_sticky=False) #,plot_width=500,plot_height=500) toolbar_sticky=False,plot_width=920)
# add watermark # add watermark
plot.extra_y_ranges = {"watermark": watermarkrange} plot.extra_y_ranges = {"watermark": watermarkrange}
@@ -2356,6 +2375,7 @@ def interactive_multiflex(datadf,xparam,yparam,groupby,extratitle='',
plot.title.text = title plot.title.text = title
plot.title.text_font_size=value("1.0em") plot.title.text_font_size=value("1.0em")
plot.sizing_mode = 'scale_width'
plot.image_url([watermarkurl],watermarkx,watermarky, plot.image_url([watermarkurl],watermarkx,watermarky,
watermarkw,watermarkh, watermarkw,watermarkh,
@@ -2581,6 +2601,7 @@ def interactive_cum_flex_chart2(theworkouts,promember=0,
# add watermark # add watermark
plot.extra_y_ranges = {"watermark": watermarkrange} plot.extra_y_ranges = {"watermark": watermarkrange}
plot.extra_x_ranges = {"watermark": watermarkrange} plot.extra_x_ranges = {"watermark": watermarkrange}
plot.sizing_mode = 'scale_width'
plot.image_url([watermarkurl],watermarkx,watermarky, plot.image_url([watermarkurl],watermarkx,watermarky,
watermarkw,watermarkh, watermarkw,watermarkh,
@@ -2764,7 +2785,10 @@ def interactive_cum_flex_chart2(theworkouts,promember=0,
title="Max Work per Stroke",callback=callback) title="Max Work per Stroke",callback=callback)
callback.args["maxwork"] = slider_work_max callback.args["maxwork"] = slider_work_max
try:
distmax = 100+100*int(datadf['distance'].max()/100.) distmax = 100+100*int(datadf['distance'].max()/100.)
except KeyError:
distmax = 1000.
slider_dist_min = Slider(start=0,end=distmax,value=0,step=1, slider_dist_min = Slider(start=0,end=distmax,value=0,step=1,
title="Min Distance",callback=callback) title="Min Distance",callback=callback)
@@ -2785,6 +2809,8 @@ def interactive_cum_flex_chart2(theworkouts,promember=0,
), ),
plot]) plot])
layout.sizing_mode = 'scale_width'
script, div = components(layout) script, div = components(layout)
js_resources = INLINE.render_js() js_resources = INLINE.render_js()
css_resources = INLINE.render_css() css_resources = INLINE.render_css()
@@ -2984,8 +3010,6 @@ def interactive_flex_chart2(id=0,promember=0,
sizing_mode = 'fixed' # 'scale_width' also looks nice with this example
plot = Figure(x_axis_type=x_axis_type,y_axis_type=y_axis_type, plot = Figure(x_axis_type=x_axis_type,y_axis_type=y_axis_type,
tools=TOOLS, tools=TOOLS,
toolbar_sticky=False toolbar_sticky=False
@@ -2996,6 +3020,7 @@ def interactive_flex_chart2(id=0,promember=0,
# add watermark # add watermark
plot.extra_y_ranges = {"watermark": watermarkrange} plot.extra_y_ranges = {"watermark": watermarkrange}
plot.extra_x_ranges = {"watermark": watermarkrange} plot.extra_x_ranges = {"watermark": watermarkrange}
plot.sizing_mode = 'scale_width'
plot.image_url([watermarkurl],watermarkx,watermarky, plot.image_url([watermarkurl],watermarkx,watermarky,
watermarkw,watermarkh, watermarkw,watermarkh,
@@ -3324,6 +3349,8 @@ def interactive_flex_chart2(id=0,promember=0,
), ),
plot]) plot])
layout.sizing_mode = 'scale_width'
script, div = components(layout) script, div = components(layout)
js_resources = INLINE.render_js() js_resources = INLINE.render_js()
css_resources = INLINE.render_css() css_resources = INLINE.render_css()
@@ -3489,6 +3516,8 @@ def thumbnail_flex_chart(rowdata,id=0,promember=0,
# plot.sizing_mode = 'scale_width'
plot.sizing_mode = 'fixed'
plot.toolbar.logo = None plot.toolbar.logo = None
plot.toolbar_location = None plot.toolbar_location = None
#plot.yaxis.visible = False #plot.yaxis.visible = False
@@ -3598,6 +3627,7 @@ def interactive_bar_chart(id=0,promember=0):
# add watermark # add watermark
plot.extra_y_ranges = {"watermark": watermarkrange} plot.extra_y_ranges = {"watermark": watermarkrange}
plot.extra_x_ranges = {"watermark": watermarkrange} plot.extra_x_ranges = {"watermark": watermarkrange}
plot.sizing_mode = 'scale_width'
plot.image_url([watermarkurl],0.01,0.99, plot.image_url([watermarkurl],0.01,0.99,
watermarkw,watermarkh, watermarkw,watermarkh,
@@ -3765,6 +3795,7 @@ def interactive_multiple_compare_chart(ids,xparam,yparam,plottype='line',
# add watermark # add watermark
plot.extra_y_ranges = {"watermark": watermarkrange} plot.extra_y_ranges = {"watermark": watermarkrange}
plot.extra_x_ranges = {"watermark": watermarkrange} plot.extra_x_ranges = {"watermark": watermarkrange}
plot.sizing_mode = 'scale_width'
plot.image_url([watermarkurl],0.05,0.9, plot.image_url([watermarkurl],0.05,0.9,
watermarkw,watermarkh, watermarkw,watermarkh,
@@ -4009,6 +4040,7 @@ def interactive_comparison_chart(id1=0,id2=0,xparam='distance',yparam='spm',
# add watermark # add watermark
plot.extra_y_ranges = {"watermark": watermarkrange} plot.extra_y_ranges = {"watermark": watermarkrange}
plot.extra_x_ranges = {"watermark": watermarkrange} plot.extra_x_ranges = {"watermark": watermarkrange}
plot.sizing_mode = 'scale_width'
plot.image_url([watermarkurl],0.05,watermarky, plot.image_url([watermarkurl],0.05,watermarky,
watermarkw,watermarkh, watermarkw,watermarkh,
@@ -4139,6 +4171,7 @@ def interactive_otw_advanced_pace_chart(id=0,promember=0):
# add watermark # add watermark
plot.extra_y_ranges = {"watermark": watermarkrange} plot.extra_y_ranges = {"watermark": watermarkrange}
plot.extra_x_ranges = {"watermark": watermarkrange} plot.extra_x_ranges = {"watermark": watermarkrange}
plot.sizing_mode = 'scale_width'
plot.image_url([watermarkurl],watermarkx,watermarky, plot.image_url([watermarkurl],watermarkx,watermarky,
watermarkw,watermarkh, watermarkw,watermarkh,
+28
View File
@@ -32,6 +32,34 @@ import courses
from rowers.tasks import handle_check_race_course from rowers.tasks import handle_check_race_course
def get_todays_micro(plan,thedate=date.today()):
thismicro = None
thismacro = TrainingMacroCycle.objects.filter(
plan=plan,
startdate__lte = thedate,
enddate__gte = thedate
)
if thismacro:
thismeso = TrainingMesoCycle.objects.filter(
plan=thismacro[0],
startdate__lte = thedate,
enddate__gte = thedate
)
if thismeso:
thismicro = TrainingMicroCycle.objects.filter(
plan=thismeso[0],
startdate__lte = thedate,
enddate__gte = thedate
)
if thismicro:
thismicro = thismicro[0]
return thismicro
# Low Level functions - to be called by higher level methods # Low Level functions - to be called by higher level methods
def add_workouts_plannedsession(ws,ps,r): def add_workouts_plannedsession(ws,ps,r):
result = 0 result = 0
+10 -10
View File
@@ -1382,7 +1382,7 @@ def handle_makeplot(f1, f2, t, hrdata, plotnr, imagename,
@app.task @app.task
def handle_sendemail_invite(email, name, code, teamname, manager, def handle_sendemail_invite(email, name, code, teamname, manager,
debug=False,**kwargs): debug=False,**kwargs):
fullemail = name + ' <' + email + '>' fullemail = email
subject = 'Invitation to join team ' + teamname subject = 'Invitation to join team ' + teamname
siteurl = SITE_URL siteurl = SITE_URL
@@ -1414,7 +1414,7 @@ def handle_sendemailnewresponse(first_name, last_name,
comment, comment,
workoutname, workoutid, commentid, workoutname, workoutid, commentid,
debug=False,**kwargs): debug=False,**kwargs):
fullemail = first_name + ' ' + last_name + ' <' + email + '>' fullemail = email
from_email = 'Rowsandall <info@rowsandall.com>' from_email = 'Rowsandall <info@rowsandall.com>'
subject = 'New comment on workout ' + workoutname subject = 'New comment on workout ' + workoutname
@@ -1451,7 +1451,7 @@ def handle_sendemailnewcomment(first_name,
fullemail = first_name + ' ' + last_name + ' <' + email + '>' fullemail = email
from_email = 'Rowsandall <info@rowsandall.com>' from_email = 'Rowsandall <info@rowsandall.com>'
subject = 'New comment on workout ' + workoutname subject = 'New comment on workout ' + workoutname
@@ -1480,7 +1480,7 @@ def handle_sendemailnewcomment(first_name,
@app.task @app.task
def handle_sendemail_request(email, name, code, teamname, requestor, id, def handle_sendemail_request(email, name, code, teamname, requestor, id,
debug=False,**kwargs): debug=False,**kwargs):
fullemail = name + ' <' + email + '>' fullemail = email
subject = 'Request to join team ' + teamname subject = 'Request to join team ' + teamname
from_email = 'Rowsandall <info@rowsandall.com>' from_email = 'Rowsandall <info@rowsandall.com>'
@@ -1506,7 +1506,7 @@ def handle_sendemail_request(email, name, code, teamname, requestor, id,
@app.task @app.task
def handle_sendemail_request_accept(email, name, teamname, managername, def handle_sendemail_request_accept(email, name, teamname, managername,
debug=False,**kwargs): debug=False,**kwargs):
fullemail = name + ' <' + email + '>' fullemail = email
subject = 'Welcome to ' + teamname subject = 'Welcome to ' + teamname
from_email = 'Rowsandall <info@rowsandall.com>' from_email = 'Rowsandall <info@rowsandall.com>'
@@ -1530,7 +1530,7 @@ def handle_sendemail_request_accept(email, name, teamname, managername,
@app.task @app.task
def handle_sendemail_request_reject(email, name, teamname, managername, def handle_sendemail_request_reject(email, name, teamname, managername,
debug=False,**kwargs): debug=False,**kwargs):
fullemail = name + ' <' + email + '>' fullemail = email
subject = 'Your application to ' + teamname + ' was rejected' subject = 'Your application to ' + teamname + ' was rejected'
from_email = 'Rowsandall <info@rowsandall.com>' from_email = 'Rowsandall <info@rowsandall.com>'
@@ -1553,7 +1553,7 @@ def handle_sendemail_request_reject(email, name, teamname, managername,
@app.task @app.task
def handle_sendemail_member_dropped(email, name, teamname, managername, def handle_sendemail_member_dropped(email, name, teamname, managername,
debug=False,**kwargs): debug=False,**kwargs):
fullemail = name + ' <' + email + '>' fullemail = email
subject = 'You were removed from ' + teamname subject = 'You were removed from ' + teamname
from_email = 'Rowsandall <info@rowsandall.com>' from_email = 'Rowsandall <info@rowsandall.com>'
@@ -1578,7 +1578,7 @@ def handle_sendemail_member_dropped(email, name, teamname, managername,
def handle_sendemail_team_removed(email, name, teamname, managername, def handle_sendemail_team_removed(email, name, teamname, managername,
debug=False,**kwargs): debug=False,**kwargs):
fullemail = name + ' <' + email + '>' fullemail = email
subject = 'You were removed from ' + teamname subject = 'You were removed from ' + teamname
from_email = 'Rowsandall <info@rowsandall.com>' from_email = 'Rowsandall <info@rowsandall.com>'
@@ -1602,7 +1602,7 @@ def handle_sendemail_team_removed(email, name, teamname, managername,
@app.task @app.task
def handle_sendemail_invite_reject(email, name, teamname, managername, def handle_sendemail_invite_reject(email, name, teamname, managername,
debug=False,**kwargs): debug=False,**kwargs):
fullemail = managername + ' <' + email + '>' fullemail = email
subject = 'Your invitation to ' + name + ' was rejected' subject = 'Your invitation to ' + name + ' was rejected'
from_email = 'Rowsandall <info@rowsandall.com>' from_email = 'Rowsandall <info@rowsandall.com>'
@@ -1626,7 +1626,7 @@ def handle_sendemail_invite_reject(email, name, teamname, managername,
@app.task @app.task
def handle_sendemail_invite_accept(email, name, teamname, managername, def handle_sendemail_invite_accept(email, name, teamname, managername,
debug=False,**kwargs): debug=False,**kwargs):
fullemail = managername + ' <' + email + '>' fullemail = email
subject = 'Your invitation to ' + name + ' was accepted' subject = 'Your invitation to ' + name + ' was accepted'
from_email = 'Rowsandall <info@rowsandall.com>' from_email = 'Rowsandall <info@rowsandall.com>'
+1 -1
View File
@@ -15,7 +15,7 @@ from django.contrib.auth.models import User
@app.task @app.task
def addcomment2(userid,id): def addcomment2(userid,id,debug=False):
time.sleep(5) time.sleep(5)
# w = Workout.objects.get(id=id) # w = Workout.objects.get(id=id)
-16
View File
@@ -1,16 +0,0 @@
{% extends "basenofilters.html" %}
{% load staticfiles %}
{% load rowerfilters %}
{% block title %}Rowsandall - Bad Request {% endblock %}
{% block content %}
<div class="grid_12">
<h1>Bad Request</h1>
<p>
HTTP Error 400 Bad Request.
</p>
</div>
{% endblock %}
-18
View File
@@ -1,18 +0,0 @@
{% extends "basenofilters.html" %}
{% load staticfiles %}
{% load rowerfilters %}
{% block title %}Rowsandall - forbidden {% endblock %}
{% block content %}
<div class="grid_12">
<h1>Forbidden</h1>
<p>
Access forbidden. You probably tried to access functionality on a workout,
planned session
or chart that is not owned by you.
</p>
</div>
{% endblock %}
-15
View File
@@ -1,15 +0,0 @@
{% extends "basenofilters.html" %}
{% load staticfiles %}
{% block title %}Rowsandall - not found {% endblock %}
{% block content %}
<div class="grid_12">
<h1>Error 404 Page not found</h1>
<p>
We could not find the page on our server.
</p>
</div>
{% endblock %}
-21
View File
@@ -1,21 +0,0 @@
{% extends "basenofilters.html" %}
{% load staticfiles %}
{% block title %}Rowsandall - error {% endblock %}
{% block content %}
<div class="grid_12">
<h1>Error 500 Internal Server Error</h1>
<p>
The site reported an internal server error. The site developer has been
notified automatically with a full error report. You can help the developer
by reporting an issue on Bitbucket using the button below.
</p>
<div class="grid_2 alpha">
<a class="button red small" href="https://bitbucket.org/sanderroosendaal/rowsandall/issues/new">Report an issue</a>
</div>
</div>
{% endblock %}
-578
View File
@@ -1,578 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
<script src="/static/cookielaw/js/cookielaw.js"></script>
<link rel="stylesheet" href="/static/css/bokeh-0.12.3.min.css" type="text/css" />
<link rel="stylesheet" href="/static/css/bokeh-widgets-0.12.3.min.css" type="text/css" />
<link rel="shortcut icon" href="/static/img/favicon.ico" type="image/x-icon" />
<link rel="icon" sizes="32x32" href="/static/img/favicon-32x32.png" type="image/png"/>
<link rel="icon" sizes="64x64" href="/static/img/favicon-64x64.png" type="image/png"/>
<link rel="icon" sizes="192x192" href="/static/img/favicon-192x192.png" type="image/png"/>
<link rel="icon" sizes="16x16" href="/static/img/favicon-16x16.png" type="image/png"/>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=0.67">
<title>Rowsandall</title>
<link rel="stylesheet" href="/static/css/reset.css" />
<link rel="stylesheet" href="/static/css/text.css" />
<link rel="stylesheet" href="/static/css/960_12_col.css" />
<link rel="stylesheet" href="/static/css/rowsandall.css" />
<!-- Google Analytics disabled on internal IP address
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-96318020-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
-->
</head>
<body>
<div class="container_12">
<div class="grid_12">
&nbsp;
</div>
<div class="grid_12">
<div id="logo" class="grid_6 alpha">
<p><a href="/"><img src="/static/img/logo7.png"
alt="Rowsandall logo" height="80"></a></p>
</div>
<div class="grid_6 omega">
<div class="grid_4 alpha">
<div class="grid_1 alpha">
<p id="header">
<a class="button gray small" href="/rowers/videos">Videos</a></p>
</div>
<div class="grid_2">
<p id="header">
<a class="button gray small" href="http://analytics.rowsandall.com/">Rowing Analytics BLOG</a></p>
</div>
<div class="grid_1 omega">
<p id="header">
<a class="button gray small" href="/rowers/email">Contact</a>
</p>
</div>
<div class="grid_4 alpha">
<p>Free Data and Analysis. For Rowers. By Rowers.</p>
</div>
</div>
<div class="grid_1">
<div class="grid_1 tooltip">
<p><a class="button gray small" href="/login/">login</a> </p>
</div>
<div class="grid_1">
<p>&nbsp</p>
</div>
</div>
<div class="grid_1 omega">
<div class="grid_1"><a class="button green small" href="/rowers/promembership">Upgrade to Pro</a></div>
</div>
</div>
</div>
<div class="grid_12">
<div class="grid_1 alpha tooltip">
<p><a class="button green small" href="/rowers/register">Register (free)</a></p>
</div>
<div class="grid_1 tooltip">
<p>&nbsp;</p>
</div>
<div class="grid_2 tooltip">
<p>&nbsp;</p>
</div>
<div class="grid_1 tooltip">
<p>&nbsp;</p>
</div>
<div class="grid_2 tooltip">
<p>&nbsp;</p>
</div>
<div class="grid_1 tooltip">
<p>&nbsp;</p>
</div>
</div>
<div class="clear"></div>
<div class="grid_12">
</div>
<div class="grid_12">
<div class="grid_12">
<h1>Error 502 Bad Gateway</h1>
<p>
No valid server response received. This can have multiple reasons,
including time-outs or reaching the capacity limit.
</p>
</div>
</div>
<div class="clear"></div>
<div class="grid_12 omega" >
<p id="footer"></p>
<div class="grid_2 alpha">
<p id="footer"><a href="/rowers/email/">&copy; Sander Roosendaal</a></p>
</div>
<div class="grid_1">
<p id="footer">
<a href="/rowers/about">About</a></p>
</div>
<div class="grid_1">
<p id="footer">
<a href="/rowers/brochure">Brochure</a></p>
</div>
<div class="grid_1">
<p id="footer">
<a href="/rowers/developers">Develop</a></p>
</div>
<div class="grid_1">
<p id="footer">
<a href="/rowers/legal">Legal</a></p>
</div>
<div class="grid_1">
<p id="footer">
<a href="/rowers/partners">Partners</a></p>
</div>
<div class="grid_1">
<p id="footer">
<a href="/rowers/physics">Physics</a></p>
</div>
<div class="grid_2">
<p id="footer">
<a href="http://analytics.rowsandall.com/">Rowing Analytics BLOG</a></p>
</div>
<div class="grid_2 omega">
<p id="footer">
<a href="https://www.facebook.com/groups/rowsandall/">Facebook group</a></p>
</div>
</div>
</div>
<!-- end container -->
<link rel="stylesheet" href="/static/debug_toolbar/css/print.css" type="text/css" media="print" />
<link rel="stylesheet" href="/static/debug_toolbar/css/toolbar.css" type="text/css" />
<!-- Prevent our copy of jQuery from registering as an AMD module on sites that use RequireJS. -->
<script src="/static/debug_toolbar/js/jquery_pre.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="/static/debug_toolbar/js/jquery_post.js"></script>
<script src="/static/debug_toolbar/js/toolbar.js"></script>
<div id="djDebug" class="djdt-hidden" dir="ltr"
data-store-id="b03ff2a671fc45f29549fcefbad74672" data-render-panel-url="/__debug__/render_panel/"
>
<div class="djdt-hidden" id="djDebugToolbar">
<ul id="djDebugPanelList">
<li><a id="djHideToolBarButton" href="#" title="Hide toolbar">Hide &#187;</a></li>
<li class="djDebugPanelButton">
<input type="checkbox" data-cookie="djdtVersionsPanel" checked="checked" title="Disable for next and successive requests" />
<a href="#" title="Versions" class="VersionsPanel">
Versions
<br /><small>Django 1.9.5</small>
</a>
</li>
<li class="djDebugPanelButton">
<input type="checkbox" data-cookie="djdtTimerPanel" checked="checked" title="Disable for next and successive requests" />
<div class="djdt-contentless">
Time
<br /><small>Total: 456.00ms</small>
</div>
</li>
<li class="djDebugPanelButton">
<input type="checkbox" data-cookie="djdtSettingsPanel" checked="checked" title="Disable for next and successive requests" />
<a href="#" title="Settings from &lt;code&gt;rowsandall_app.settings_dev&lt;/code&gt;" class="SettingsPanel">
Settings
</a>
</li>
<li class="djDebugPanelButton">
<input type="checkbox" data-cookie="djdtHeadersPanel" checked="checked" title="Disable for next and successive requests" />
<a href="#" title="Headers" class="HeadersPanel">
Headers
</a>
</li>
<li class="djDebugPanelButton">
<input type="checkbox" data-cookie="djdtRequestPanel" checked="checked" title="Disable for next and successive requests" />
<a href="#" title="Request" class="RequestPanel">
Request
<br /><small>error500_view</small>
</a>
</li>
<li class="djDebugPanelButton">
<input type="checkbox" data-cookie="djdtSQLPanel" checked="checked" title="Disable for next and successive requests" />
<a href="#" title="SQL queries from 0 connections" class="SQLPanel">
SQL
<br /><small>0 queries in 0.00ms</small>
</a>
</li>
<li class="djDebugPanelButton">
<input type="checkbox" data-cookie="djdtStaticFilesPanel" checked="checked" title="Disable for next and successive requests" />
<a href="#" title="Static files (1470 found, 0 used)" class="StaticFilesPanel">
Static files
<br /><small>0 files used</small>
</a>
</li>
<li class="djDebugPanelButton">
<input type="checkbox" data-cookie="djdtTemplatesPanel" checked="checked" title="Disable for next and successive requests" />
<a href="#" title="Templates (3 rendered)" class="TemplatesPanel">
Templates
<br /><small>500.html</small>
</a>
</li>
<li class="djDebugPanelButton">
<input type="checkbox" data-cookie="djdtCachePanel" checked="checked" title="Disable for next and successive requests" />
<a href="#" title="Cache calls from 1 backend" class="CachePanel">
Cache
<br /><small>0 calls in 0.00ms</small>
</a>
</li>
<li class="djDebugPanelButton">
<input type="checkbox" data-cookie="djdtSignalsPanel" checked="checked" title="Disable for next and successive requests" />
<a href="#" title="Signals" class="SignalsPanel">
Signals
<br /><small>17 receivers of 12 signals</small>
</a>
</li>
<li class="djDebugPanelButton">
<input type="checkbox" data-cookie="djdtLoggingPanel" checked="checked" title="Disable for next and successive requests" />
<a href="#" title="Log messages" class="LoggingPanel">
Logging
<br /><small>0 messages</small>
</a>
</li>
<li class="djDebugPanelButton">
<input type="checkbox" data-cookie="djdtRedirectsPanel" title="Enable for next and successive requests" />
<div class="djdt-contentless djdt-disabled">
Intercept redirects
</div>
</li>
</ul>
</div>
<div class="djdt-hidden" id="djDebugToolbarHandle">
<span title="Show toolbar" id="djShowToolBarButton">&#171;</span>
</div>
<div id="VersionsPanel" class="djdt-panelContent">
<div class="djDebugPanelTitle">
<a href="" class="djDebugClose"></a>
<h3>Versions</h3>
</div>
<div class="djDebugPanelContent">
<img src="/static/debug_toolbar/img/ajax-loader.gif" alt="loading" class="djdt-loader" />
<div class="djdt-scroll"></div>
</div>
</div>
<div id="SettingsPanel" class="djdt-panelContent">
<div class="djDebugPanelTitle">
<a href="" class="djDebugClose"></a>
<h3>Settings from <code>rowsandall_app.settings_dev</code></h3>
</div>
<div class="djDebugPanelContent">
<img src="/static/debug_toolbar/img/ajax-loader.gif" alt="loading" class="djdt-loader" />
<div class="djdt-scroll"></div>
</div>
</div>
<div id="HeadersPanel" class="djdt-panelContent">
<div class="djDebugPanelTitle">
<a href="" class="djDebugClose"></a>
<h3>Headers</h3>
</div>
<div class="djDebugPanelContent">
<img src="/static/debug_toolbar/img/ajax-loader.gif" alt="loading" class="djdt-loader" />
<div class="djdt-scroll"></div>
</div>
</div>
<div id="RequestPanel" class="djdt-panelContent">
<div class="djDebugPanelTitle">
<a href="" class="djDebugClose"></a>
<h3>Request</h3>
</div>
<div class="djDebugPanelContent">
<img src="/static/debug_toolbar/img/ajax-loader.gif" alt="loading" class="djdt-loader" />
<div class="djdt-scroll"></div>
</div>
</div>
<div id="SQLPanel" class="djdt-panelContent">
<div class="djDebugPanelTitle">
<a href="" class="djDebugClose"></a>
<h3>SQL queries from 0 connections</h3>
</div>
<div class="djDebugPanelContent">
<img src="/static/debug_toolbar/img/ajax-loader.gif" alt="loading" class="djdt-loader" />
<div class="djdt-scroll"></div>
</div>
</div>
<div id="StaticFilesPanel" class="djdt-panelContent">
<div class="djDebugPanelTitle">
<a href="" class="djDebugClose"></a>
<h3>Static files (1470 found, 0 used)</h3>
</div>
<div class="djDebugPanelContent">
<img src="/static/debug_toolbar/img/ajax-loader.gif" alt="loading" class="djdt-loader" />
<div class="djdt-scroll"></div>
</div>
</div>
<div id="TemplatesPanel" class="djdt-panelContent">
<div class="djDebugPanelTitle">
<a href="" class="djDebugClose"></a>
<h3>Templates (3 rendered)</h3>
</div>
<div class="djDebugPanelContent">
<img src="/static/debug_toolbar/img/ajax-loader.gif" alt="loading" class="djdt-loader" />
<div class="djdt-scroll"></div>
</div>
</div>
<div id="CachePanel" class="djdt-panelContent">
<div class="djDebugPanelTitle">
<a href="" class="djDebugClose"></a>
<h3>Cache calls from 1 backend</h3>
</div>
<div class="djDebugPanelContent">
<img src="/static/debug_toolbar/img/ajax-loader.gif" alt="loading" class="djdt-loader" />
<div class="djdt-scroll"></div>
</div>
</div>
<div id="SignalsPanel" class="djdt-panelContent">
<div class="djDebugPanelTitle">
<a href="" class="djDebugClose"></a>
<h3>Signals</h3>
</div>
<div class="djDebugPanelContent">
<img src="/static/debug_toolbar/img/ajax-loader.gif" alt="loading" class="djdt-loader" />
<div class="djdt-scroll"></div>
</div>
</div>
<div id="LoggingPanel" class="djdt-panelContent">
<div class="djDebugPanelTitle">
<a href="" class="djDebugClose"></a>
<h3>Log messages</h3>
</div>
<div class="djDebugPanelContent">
<img src="/static/debug_toolbar/img/ajax-loader.gif" alt="loading" class="djdt-loader" />
<div class="djdt-scroll"></div>
</div>
</div>
<div id="djDebugWindow" class="djdt-panelContent"></div>
</div>
</body>
</html>
+13 -18
View File
@@ -1,10 +1,9 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% block title %}Rowsandall - About us{% endblock title %} {% block title %}Rowsandall - About us{% endblock title %}
{% block content %} {% block main %}
{% load rowerfilters %} {% load rowerfilters %}
<div class="grid_4 alpha">
<h2>Welcome to Rowsandall.com</h2> <h2>Welcome to Rowsandall.com</h2>
<p>Rowsandall.com is an online tool for indoor and On The Water (OTW) rowers. <p>Rowsandall.com is an online tool for indoor and On The Water (OTW) rowers.
It accepts workout data from a number of devices and applications. It It accepts workout data from a number of devices and applications. It
@@ -78,19 +77,13 @@
<a href="/rowers/compatibility">here</a>. <a href="/rowers/compatibility">here</a>.
</div>
<div class="grid_4">
<div class="grid_4">
<h2>Credits</h2> <h2>Credits</h2>
<p>The project is based on python plotting code by <p>The project is based on python plotting code by
Greg Smith (<a href="https://quantifiedrowing.wordpress.com/" rel="nofollow">https://quantifiedrowing.wordpress.com/</a>) Greg Smith (<a href="https://quantifiedrowing.wordpress.com/" rel="nofollow">https://quantifiedrowing.wordpress.com/</a>)
and inspired by the RowPro Dan Burpee spreadsheet and inspired by the RowPro Dan Burpee spreadsheet
(<a href="http://www.sub7irc.com/RP_Split_Template.zip" rel="nofollow">http://www.sub7irc.com/RP_Split_Template.zip</a>).</p> (<a href="http://www.sub7irc.com/RP_Split_Template.zip" rel="nofollow">http://www.sub7irc.com/RP_Split_Template.zip</a>).</p>
</div>
<div class="grid_4">
<h2>Advanced Analysis, Coaching and Planning (Premium Features)</h2> <h2>Advanced Analysis, Coaching and Planning (Premium Features)</h2>
@@ -119,12 +112,9 @@ and inspired by the RowPro Dan Burpee spreadsheet
</div>
</div>
<div class="grid_4 omega"> {% if user.rower.rowerplan == 'basic' and user.rower.protrialexpires|date_dif == 1 %}
{% if user.rower.rowerplan == 'basic' and user.rower.protrialexpires|date_dif == 1 %} <h2>Free Trial</h2>
<h2>Free Trial</h2>
<p> <p>
You qualify for a 14 day free trial. No credit card needed. You qualify for a 14 day free trial. No credit card needed.
Try out Pro membership for two weeks. Click the button below to Try out Pro membership for two weeks. Click the button below to
@@ -188,5 +178,10 @@ and inspired by the RowPro Dan Burpee spreadsheet
<p>If, for any reason, you are not happy with your Pro membership, please let me know through the contact form. I will contact you as soon as possible to discuss how we can make things better.</p> <p>If, for any reason, you are not happy with your Pro membership, please let me know through the contact form. I will contact you as soon as possible to discuss how we can make things better.</p>
</div>
{% endblock content %} {% endblock main %}
{% block sidebar %}
{% include 'menu_help.html' %}
{% endblock %}
+26 -34
View File
@@ -1,52 +1,44 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}Rowsandall {% endblock %} {% block title %}Rowsandall Age Group Records{% endblock %}
{% block content %} {% block main %}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>
{{ interactiveplot |safe }} {{ interactiveplot |safe }}
<script>
// Set things up to resize the plot on a window resize. You can play with
// the arguments of resize_width_height() to change the plot's behavior.
var plot_resize_setup = function () {
var plotid = Object.keys(Bokeh.index)[0]; // assume we have just one plot
var plot = Bokeh.index[plotid];
var plotresizer = function() {
// arguments: use width, use height, maintain aspect ratio
plot.resize_width_height(true, false, false);
};
window.addEventListener('resize', plotresizer);
plotresizer();
};
window.addEventListener('load', plot_resize_setup);
</script>
<style>
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
html, body {height: 100%; margin:5px;}
</style>
<div id="workouts" class="grid_12 alpha"> <h1>Interactive Plot</h1>
<ul class="main-content">
<h1>Interactive Plot</h1> <li class="maxheight grid_4">
<p>This chart shows the
<p>This chart shows the <a href="http://www.concept2.com/indoor-rowers/racing/records/world">Indoor Rower World Records</a> for your gender and <a href="http://www.concept2.com/indoor-rowers/racing/records/world">
Indoor Rower World Records
</a> for your gender and
weight class. The red dots are the official records, and hovering weight class. The red dots are the official records, and hovering
over them with your mouse shows you the name of the record holder. over them with your mouse shows you the name of the record holder.
The blue line is a fit to the data, which is used by rowsandall.com The blue line is a fit to the data, which is used by rowsandall.com
to calculate your performance assessment.</a> to calculate your performance assessment.
</p>
</li>
<li class="grid_4">
{{ the_div|safe }} {{ the_div|safe }}
</li>
</div>
</ul>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_analytics.html' %}
{% endblock %}
+16 -33
View File
@@ -1,47 +1,30 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}Rowsandall {% endblock %} {% block title %}Rowsandall Age Group CP{% endblock %}
{% block content %} {% block main %}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>
{{ interactiveplot |safe }}
<script>
// Set things up to resize the plot on a window resize. You can play with
// the arguments of resize_width_height() to change the plot's behavior.
var plot_resize_setup = function () {
var plotid = Object.keys(Bokeh.index)[0]; // assume we have just one plot
var plot = Bokeh.index[plotid];
var plotresizer = function() {
// arguments: use width, use height, maintain aspect ratio
plot.resize_width_height(true, false, false);
};
window.addEventListener('resize', plotresizer);
plotresizer();
};
window.addEventListener('load', plot_resize_setup);
</script>
<style>
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
html, body {height: 100%; margin:5px;}
</style>
<div id="workouts" class="grid_12 alpha"> {{ interactiveplot |safe }}
<h1>Interactive Plot</h1> <h1>Interactive Plot</h1>
<ul class="main-content">
<li class="maxheight grid_4">
{{ the_div|safe }} {{ the_div|safe }}
</li>
</div> </ul>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_analytics.html' %}
{% endblock %}
+101 -118
View File
@@ -1,171 +1,154 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}Rowsandall - Analysis {% endblock %} {% block title %}Rowsandall - Analysis {% endblock %}
{% block content %} {% block main %}
<h1>Analysis</h1> <h1>Analysis</h1>
<p>Functionality to analyze multiple workouts.</p> <p>Functionality to analyze multiple workouts.</p>
<div class="grid_12 alpha"> <ul class="main-content">
<div class="grid_6 alpha"> <li class="rounder">
<h2>Basic</h2> <h2>Ranking Pieces</h2>
<div class="grid_2 alpha"> <a href="/rowers/ote-bests2">
<p> <div class="vignet">
<a class="button blue small" href="/rowers/ote-bests">Ranking Pieces</a></p> <img src="/static/img/rankingpiece.png"
<p>Analyze your Concept2 ranking pieces over a date range and predict your pace on other pieces.</p> alt="Ranking Piece">
</div> </div>
<div class="grid_2"> </a>
<p> <p>
<a class="button blue small" href="/rowers/flexall">Stroke Analysis</a> Analyze your Concept2 ranking pieces over a date range and predict your pace on other pieces.
</p> </p>
</li>
<li class="rounder">
<h2>Stroke Analysis</h2>
<a href="/rowers/flexall">
<div class="vignet">
<img src="/static/img/strokeanalysis.png"
alt="Stroke Analysis">
</div>
</a>
<p> <p>
Plot all strokes in a date range and analyze several parameters (Power, Pace, SPM, Heart Rate). Plot all strokes in a date range and analyze several parameters (Power, Pace, SPM, Heart Rate).
</p> </p>
</div> </li>
<div class="grid_2 omega"> <li class="rounder">
<p class="button white small"> <h2>Power Histogram</h2>
Analysis Feature 3
</p>
<p>
Reserved for future functionality.
</p>
</div>
</div>
<div class="grid_6 omega">
<h2>Pro</h2>
<div class="grid_2 alpha">
<p>
{% if user|is_promember %} {% if user|is_promember %}
<a class="button blue small" href="/rowers/histo">Power Histogram</a> <a href="/rowers/histo">
{% else %} {% else %}
<a class="button blue small" href="/rowers/promembership">Power Histogram</a> <a href="/rowers/promembership">
{% endif %} {% endif %}
</p> <div class="vignet">
<img src="/static/img/histogram.png" alt="Power Histogram">
</div>
</a>
<p> <p>
Plot a power histogram of all your strokes over a date range. Plot a power histogram of all your strokes over a date range.
</p> </p>
</div> </li>
<div class="grid_2"> <li class="rounder">
<p> <h2>Statistics</h2>
{% if user|is_promember %} {% if user|is_promember %}
<a class="button blue small" href="/rowers/cumstats">Statistics</a> <a href="/rowers/cumstats">
{% else %} {% else %}
<a class="button blue small" href="/rowers/promembership">Statistics</a> <a href="/rowers/promembership">
{% endif %} {% endif %}
</p> <div class="vignet">
<p> <img src="/static/img/statistics.PNG" alt="Statistics">
BETA: Statistics of stroke metrics over a date range
</p>
</div> </div>
<div class="grid_2 omega"> </a>
<p> <p>
{% if user|is_promember %} Statistics of stroke metrics over a date range
<a class="button blue small" href="/rowers/user-boxplot-select">Box Chart</a>
{% else %}
<a class="button blue small" href="/rowers/promembership">Box Chart</a>
{% endif %}
</p> </p>
</li>
<li class="rounder">
<h2>Box Chart</h2>
{% if user|is_promember %}
<a href="/rowers/user-boxplot-select">
{% else %}
<a href="/rowers/promembership">
{% endif %}
<div class="vignet">
<img src="/static/img/boxplot.png" alt="Box Chart">
</div>
</a>
<p> <p>
BETA: Box Chart Statistics of stroke metrics over a date range BETA: Box Chart Statistics of stroke metrics over a date range
</p> </p>
</div> </li>
</div> <li class="rounder">
<h2>OTW Critical Power</h2>
<div class="grid_12 alpha">
<div class="grid_6 alpha">
<div class="grid_2 suffix_4 alpha">
<p>
<a class="button blue small" href="/rowers/ote-bests2">
Ranking Pieces 2.0</a></p>
<p>Analyze your Concept2 ranking pieces over a date range and predict your pace on other pieces.</p>
</div>
</div>
<div class="grid_6 omega">
<div class="grid_2 alpha">
<p>
{% if user|is_promember %} {% if user|is_promember %}
<a class="button blue small" href="/rowers/otw-bests">OTW Critical Power</a> <a href="/rowers/otw-bests">
{% else %} {% else %}
<a class="button blue small" href="/rowers/promembership">OTW Critical Power</a> <a href="/rowers/promembership">
{% endif %} {% endif %}
</p> <div class="vignet">
<img src="/static/img/otwcp.png" alt="OTW Critical Power">
</div>
</a>
<p> <p>
Analyse power vs piece duration to make predictions. For On-The-Water rowing. Analyse power vs piece duration to make predictions. For On-The-Water rowing.
</p> </p>
</div> </li>
<div class="grid_2"> <li class="rounder">
<p> <h2>OTE Critical Power</h2>
{% if user|is_promember %} {% if user|is_promember %}
<a class="button blue small" href="/rowers/team-compare-select/team/0/">Multi Compare</a> <a href="/rowers/ote-ranking">
{% else %} {% else %}
<a class="button blue small" href="/rowers/promembership">Multi Compare</a> <a href="/rowers/promembership">
{% endif %} {% endif %}
</p> <div class="vignet">
<p> <img src="/static/img/otecp.png" alt="OTE Critical Power">
Compare many workouts
</p>
</div> </div>
<div class="grid_2 omega"> </a>
<p>
{% if user|is_promember %}
<a class="button blue small" href="/rowers/user-multiflex-select">Trend Flex</a>
{% else %}
<a class="button blue small" href="/rowers/promembership">Trend Flex</a>
{% endif %}
</p>
<p>
Select workouts and make X-Y charts of averages over various metrics
</p>
</div>
</div>
<div class="grid_6 prefix_6 alpha">
<div class="grid_2 alpha">
<p>
{% if user|is_promember %}
<a class="button blue small" href="/rowers/ote-ranking">OTE Critical Power</a>
{% else %}
<a class="button blue small" href="/rowers/promembership">OTE Critical Power</a>
{% endif %}
</p>
<p> <p>
Analyse power vs piece duration to make predictions, for erg pieces. Analyse power vs piece duration to make predictions, for erg pieces.
</p> </p>
</div> </li>
<div class="grid_2"> <li class="rounder">
<p> <h2>Trend Flex</h2>
{% if user|is_planmember %} {% if user|is_promember %}
<a class="button blue small" href="/rowers/fitness-progress">Power Progress</a> <a href="/rowers/user-multiflex-select">
{% else %} {% else %}
<a class="button blue small" href="/rowers/promembership">Power Progress</a> <a href="/rowers/promembership">
{% endif %} {% endif %}
<div class="vignet">
<img src="/static/img/trendflex.png" alt="Trend Flex">
</div>
</a>
<p>
Select workouts and make X-Y charts of averages over various metrics
</p> </p>
</li>
<li class="rounder">
<h1>Power Progress</h1>
{% if user|is_planmember %}
<a href="/rowers/fitness-progress">
{% else %}
<a href="/rowers/promembership">
{% endif %}
<div class="vignet">
<img src="/static/img/powerprogress.png" alt="Power Progress">
</div>
</a>
<p> <p>
Monitoring power duration evidence from all your workouts. Feel free to explore. Monitoring power duration evidence from all your workouts. Feel free to explore.
</p> </p>
</div> </li>
<div class="grid_2 omega"> </ul>
<p>
{% if user|is_planmember %}
<a class="button blue small" href="/rowers/laboratory">The Labs</a>
{% else %}
<a class="button blue small" href="/rowers/promembership">The Labs</a>
{% endif %}
</p>
<p>
Undisclosed new functionality. This is still experimental and
may not make sense.
</p>
</div>
</div>
</div>
{% endblock %}
{% block sidebar %}
{% include 'menu_analytics.html' %}
{% endblock %} {% endblock %}
+6 -2
View File
@@ -1,4 +1,4 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
@@ -56,7 +56,7 @@
{% endblock %} {% endblock %}
{% block content %} {% block main %}
<h1>Your Tasks Status</h1> <h1>Your Tasks Status</h1>
@@ -117,4 +117,8 @@
{% endblock %}
{% block sidebar %}
{% include 'menu_workouts.html' %}
{% endblock %} {% endblock %}
+18 -38
View File
@@ -1,10 +1,10 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}Rowsandall Box Plot {% endblock %} {% block title %}Rowsandall Box Plot {% endblock %}
{% block content %} {% block main %}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
@@ -14,58 +14,34 @@
<div id="id_script"> <div id="id_script">
</div> </div>
<script>
// Set things up to resize the plot on a window resize. You can play with
// the arguments of resize_width_height() to change the plot's behavior.
var plot_resize_setup = function () {
var plotid = Object.keys(Bokeh.index)[0]; // assume we have just one plot
var plot = Bokeh.index[plotid];
var plotresizer = function() {
// arguments: use width, use height, maintain aspect ratio
plot.resize_width_height(true, false, false);
};
window.addEventListener('resize', plotresizer);
plotresizer();
};
window.addEventListener('load', plot_resize_setup);
</script>
<style>
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
html, body {height: 100%; margin:5px;}
</style>
<h1>Box Chart</h1>
<div class="grid_12 alpha"> <ul class="main-content">
<h1>Box Chart</h1> <li class="grid_4">
<div id="workouts" class="grid_8 alpha"> <div id="id_chart">
<div id="id_chart" class="grid_8 alpha flexplot">
{{ the_div|safe }} {{ the_div|safe }}
</div> </div>
</div> </li>
<div class="grid_4 omega"> <li class="grid_2">
<div class="grid_4"> <form enctype="multipart/form-data" action="" method="post">
<form enctype="multipart/form-data" action="/rowers/user-boxplot/{{ userid }}" method="post">
{% csrf_token %} {% csrf_token %}
<table> <table>
{{ chartform.as_table }} {{ chartform.as_table }}
</table> </table>
<div class="grid_1 prefix_2 suffix_1">
<p> <p>
<input name='workoutselectform' class="button green" type="submit" value="Submit"> <input name='workoutselectform' class="button green" type="submit" value="Submit">
</p> </p>
</div>
</form> </form>
</div> </li>
<div class="grid_4"> <li class="grid_2">
<p> <p>
You can use the form above to change the metric or filter the data. You can use the form to change the metric or filter the data.
Set Min SPM and Max SPM to select only strokes in a certain range of Set Min SPM and Max SPM to select only strokes in a certain range of
stroke rates. stroke rates.
Set Work per Stroke to a minimum value to remove "paddle" strokes or turns. Set Work per Stroke to a minimum value to remove "paddle" strokes or turns.
</p> </p>
</div> </li>
</div> </ul>
</div>
{% endblock %} {% endblock %}
@@ -92,3 +68,7 @@
</script> </script>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_analytics.html' %}
{% endblock %}
+10 -9
View File
@@ -1,5 +1,5 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% block title %}Rowsandall Brochure{% endblock title %} {% block title %}Rowsandall Brochure{% endblock title %}
{% block meta %} {% block meta %}
<style> <style>
@@ -7,19 +7,20 @@
object { width: 900px; height: 5000px } object { width: 900px; height: 5000px }
</style> </style>
{% endblock meta %} {% endblock meta %}
{% block content %} {% block main %}
<div class="grid_12 alpha"> <h2>Read our Brochure</h2>
<h2>Read our Brochure</h2>
<div id="container"> <div id="container">
<object id="obj" data="/static/brochure WEB.pdf" > <object id="obj" data="/static/brochure WEB.pdf" >
object can't be rendered object can't be rendered
</object> </object>
</div> </div>
<!-- <!--
<embed src="/static/brochure WEB.pdf" width="960" height="650"> <embed src="/static/brochure WEB.pdf" width="960" height="650">
--> -->
</div> {% endblock %}
{% endblock content %} {% block sidebar %}
{% include 'menu_help.html' %}
{% endblock %}
+31 -25
View File
@@ -1,35 +1,36 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}Workouts{% endblock %} {% block title %}Workouts{% endblock %}
{% block content %} {% block main %}
<h1>Available on C2 Logbook</h1> <h1>Available on C2 Logbook</h1>
{% if workouts %} <ul class="main-content">
<div class="grid_2 alpha "> {% if workouts %}
<a href="/rowers/workout/c2import/all/{{ page }}" class="button gray">Import all NEW</a> <li class="grid_2">
</div> <a href="/rowers/workout/c2import/all/{{ page }}">Import all NEW</a>
<div class="grid_6">
<p>This imports all workouts that have not been imported to rowsandall.com. <p>This imports all workouts that have not been imported to rowsandall.com.
The action may take a longer time to process, so please be patient. Click on Import in the list below to import an individual workout. The action may take a longer time to process, so please be patient. Click on Import in the list below to import an individual workout.
</p> </p>
</div> </li>
<li class="grid_2">
<div class="grid_2"> <p>
<span>
{% if page > 1 %} {% if page > 1 %}
<a class="button gray" href="/rowers/workout/c2list/{{ page|add:-1 }}">&lt</a> <a class="wh" title="Previous" href="/rowers/workout/c2list/{{ page|add:-1 }}">
{% else %} <i class="fas fa-arrow-alt-left"></i>
&nbsp; </a>
{% endif %} {% endif %}
</div> <a class="wh" title="Next" href="/rowers/workout/c2list/{{ page|add:1 }}">
<div class="grid_2 omega"> <i class="fas fa-arrow-alt-right"></i>
<a class="button gray" href="/rowers/workout/c2list/{{ page|add:1 }}">&gt</a> </a>
</div> </span>
</p>
<div class="grid_12 alpha"> </li>
<table width="70%" class="listtable"> <li class="grid_4">
<table width="70%" class="listtable">
<thead> <thead>
<tr> <tr>
<th> Import </th> <th> Import </th>
@@ -60,9 +61,14 @@
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
</div> </li>
{% else %} {% else %}
<p> No workouts found </p> <p> No workouts found </p>
{% endif %} {% endif %}
</ul>
{% endblock %}
{% block sidebar %}
{% include 'menu_workouts.html' %}
{% endblock %} {% endblock %}
+7 -7
View File
@@ -1,11 +1,10 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% block title %}CrewNerd Summary loading{% endblock %} {% block title %}CrewNerd Summary loading{% endblock %}
{% block content %} {% block main %}
<form enctype="multipart/form-data" action="{{ formloc }}" method="post"> <form enctype="multipart/form-data" action="{{ formloc }}" method="post">
<div id="left" class="grid_6 alpha">
<h1>Upload Workout Summary File (CrewNerd)</h1> <h1>Upload Workout Summary File (CrewNerd)</h1>
{% if form.errors %} {% if form.errors %}
<p style="color: red;"> <p style="color: red;">
@@ -17,9 +16,10 @@
{{ form.as_table }} {{ form.as_table }}
</table> </table>
{% csrf_token %} {% csrf_token %}
<div id="formbutton" class="grid_1 prefix_4 suffix_1">
<input type="submit" value="Submit"> <input type="submit" value="Submit">
</div>
</div>
</form> </form>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_workout.html' %}
{% endblock %}
+14 -31
View File
@@ -1,4 +1,4 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block scripts %} {% block scripts %}
@@ -7,49 +7,32 @@
{% block title %}{{ course.name }} {% endblock %} {% block title %}{{ course.name }} {% endblock %}
{% block og_title %}{{ course.name }} {% endblock %} {% block og_title %}{{ course.name }} {% endblock %}
{% block content %} {% block main %}
<div class="grid_12 alpha"> <h1>{{ course.name }}</h1>
<div class="grid_2 alpha">
{% if nosessions %}
<a class="button small red" href="/rowers/courses/{{ course.id }}/delete">Delete</a>
{% else %}
<a class="button small red" href="/rowers/courses/{{ course.id }}/replace">
Update</a>
{% endif %}
</div>
<div class="grid_2">
{% if course.manager == rower %}
<a class="button small gray" href="/rowers/courses/{{ course.id }}">View Course</a>
{% else %}
&nbsp;
{% endif %}
</div>
<div class="grid_2">
<a class="button small gray" href="/rowers/list-courses">Courses</a>
</div>
</div>
<div class="grid_12 alpha">
<h1>{{ course.name }}</h1> <ul class="main-content">
<li class="grid_2">
<div class="grid_6 alpha">
<form id="course_form" method="post"> <form id="course_form" method="post">
<table> <table>
{{ form.as_table }} {{ form.as_table }}
</table> </table>
{% csrf_token %} {% csrf_token %}
<div id="formbutton" class="grid_1 prefix_4 suffix_1 alpha">
<input class="button green" type="submit" value="Submit"> <input class="button green" type="submit" value="Submit">
</div>
</form> </form>
</div> </li>
<div class="grid_6 omega"> <li class="grid_2">
<div class="mapdiv">
{{ mapdiv|safe }} {{ mapdiv|safe }}
{{ mapscript|safe }} {{ mapscript|safe }}
</div> </div>
</li>
</div> </ul>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_racing.html' %}
{% endblock %}
+22 -16
View File
@@ -1,4 +1,4 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
@@ -15,14 +15,16 @@
</script> </script>
{% endblock %} {% endblock %}
{% block content %} {% block main %}
<div id="id_dropregion" class="grid_12 alpha watermark invisible"> <h1>Upload KML Course File</h1>
<ul class="main-content">
<li class="grid_4">
<div id="id_dropregion watermark invisible">
<p>Drag and drop files here </p> <p>Drag and drop files here </p>
</div> </div>
<div id="id_drop-files" class="grid_12 alpha drop-files"> <div id="id_drop-files" class="grid_12 alpha drop-files">
<form id="file_form" enctype="multipart/form-data" action="{{ formloc }}" method="post"> <form id="file_form" enctype="multipart/form-data" action="{{ formloc }}" method="post">
<div id="left" class="grid_6 alpha">
<h1>Upload KML Course File</h1>
{% if form.errors %} {% if form.errors %}
<p style="color: red;"> <p style="color: red;">
Please correct the error{{ form.errors|pluralize }} below. Please correct the error{{ form.errors|pluralize }} below.
@@ -33,21 +35,25 @@
{{ form.as_table }} {{ form.as_table }}
</table> </table>
{% csrf_token %} {% csrf_token %}
<div id="formbutton" class="grid_1 prefix_4 suffix_1"> <p>
<input class="button green" type="submit" value="Submit"> <input class="button green" type="submit" value="Submit">
</div> </p>
</div>
<div id="right" class="grid_6 omega">
&nbsp;
</div>
</form> </form>
</div>
</li>
</ul>
{% endblock %} {% endblock %}
{% block scripts %} {% block sidebar %}
{% include 'menu_racing.html' %}
{% endblock %}
{% block scripts %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script> <script>
var td = new FormData(); var td = new FormData();
@@ -169,7 +175,7 @@
}); });
$("#id_drop-files").replaceWith( $("#id_drop-files").replaceWith(
'<div id="id_waiting"><img src="/static/img/rowingtimer.gif" width="120" height="100">' '<div id="id_waiting"><img src="/static/img/rowingtimer.gif" width="120" height="100" style="width:120px">'
); );
$.ajax({ $.ajax({
data: data, data: data,
+14 -23
View File
@@ -1,4 +1,4 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block scripts %} {% block scripts %}
@@ -7,24 +7,12 @@
{% block title %}{{ course.name }} {% endblock %} {% block title %}{{ course.name }} {% endblock %}
{% block og_title %}{{ course.name }} {% endblock %} {% block og_title %}{{ course.name }} {% endblock %}
{% block content %} {% block main %}
<div class="grid_12 alpha"> <h1>Replace {{ course.name }}</h1>
<div class="grid_2 prefix_2 alpha">
{% if course.manager == rower %}
<a class="button small gray" href="/rowers/courses/{{ course.id }}">View Course</a>
{% else %}
&nbsp;
{% endif %}
</div>
<div class="grid_2">
<a class="button small gray" href="/rowers/list-courses">Courses</a>
</div>
</div>
<div class="grid_12 alpha">
<h1>Replace {{ course.name }}</h1> <ul class="main-content">
<div class="grid_8 alpha"> <li class="grid_2">
<p> <p>
This replaces the course {{ course.name }} with the course you select below for all This replaces the course {{ course.name }} with the course you select below for all
planned sessions and virtual races, and then deletes this course. planned sessions and virtual races, and then deletes this course.
@@ -34,18 +22,21 @@
{{ form.as_table }} {{ form.as_table }}
</table> </table>
{% csrf_token %} {% csrf_token %}
<div id="formbutton" class="grid_1 prefix_4 suffix_1 alpha">
<input class="button green" type="submit" value="Submit"> <input class="button green" type="submit" value="Submit">
</div>
</form> </form>
</div> </li>
<div class="grid_4 omega"> <li class="grid_2">
<div class="mapdiv">
{{ mapdiv|safe }} {{ mapdiv|safe }}
{{ mapscript|safe }} {{ mapscript|safe }}
</div> </div>
</li>
</div> </ul>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_racing.html' %}
{% endblock %}
+14 -32
View File
@@ -1,4 +1,4 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block scripts %} {% block scripts %}
@@ -7,34 +7,11 @@
{% block title %}{{ course.name }} {% endblock %} {% block title %}{{ course.name }} {% endblock %}
{% block og_title %}{{ course.name }} {% endblock %} {% block og_title %}{{ course.name }} {% endblock %}
{% block content %} {% block main %}
<div class="grid_12 alpha"> <h1>{{ course.name }}</h1>
<div class="grid_2 alpha">
{% if nosessions %}
<a class="button small red" href="/rowers/courses/{{ course.id }}/delete">Delete</a>
{% else %}
&nbsp;
{% endif %}
</div>
<div class="grid_2">
{% if course.manager == rower %}
<a class="button small gray" href="/rowers/courses/{{ course.id }}/edit">Edit</a>
{% else %}
&nbsp;
{% endif %}
</div>
<div class="grid_2">
<a class="button small gray" href="/rowers/list-courses">Courses</a>
</div>
<div class="grid_2">
<a class="button small gray" href="/rowers/courses/{{ course.id }}/emailkml">Export to KML</a>
</div>
</div>
<div class="grid_12 alpha">
<h1>{{ course.name }}</h1> <ul class="main-content">
<li class="grid_2">
<div class="grid_6 alpha">
<table class="listtable shortpadded" width="100%"> <table class="listtable shortpadded" width="100%">
<tr> <tr>
<th>Name</th><td>{{ course.name }}</td> <th>Name</th><td>{{ course.name }}</td>
@@ -46,14 +23,19 @@
<th>Notes</th><td>{{ course.notes|linebreaks }}</td> <th>Notes</th><td>{{ course.notes|linebreaks }}</td>
</tr> </tr>
</table> </table>
</div> </li>
<div class="grid_6 omega"> <li class="grid_2">
<div class="mapdiv">
{{ mapdiv|safe }} {{ mapdiv|safe }}
{{ mapscript|safe }} {{ mapscript|safe }}
</div> </div>
</li>
</div> </ul>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_racing.html' %}
{% endblock %}
+18 -2
View File
@@ -1,7 +1,23 @@
<div> {% extends "newbase.html" %}
{{ mapscript|safe }} {% load staticfiles %}
{% load rowerfilters %}
{% block scripts %}
{% include "monitorjobs.html" %}
{% endblock %}
{% block title %}{{ course.name }} {% endblock %}
{% block og_title %}{{ course.name }} {% endblock %}
{% block main %}
<h1>{{ course.name }}</h1>
<div class="mapdiv">
{{ mapdiv|safe }} {{ mapdiv|safe }}
{{ mapscript|safe }}
</div> </div>
{% endblock %}
{% block sidebar %}
{% include 'menu_racing.html' %}
{% endblock %}
+59 -175
View File
@@ -1,35 +1,16 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}Rowsandall {% endblock %} {% block title %}Rowsandall {% endblock %}
{% block content %} {% block main %}
<div id="id_css_res">
<link rel="stylesheet" href="/static/css/bokeh-0.12.3.min.css" type="text/css" />
<link rel="stylesheet" href="/static/css/bokeh-widgets-0.12.3.min.css" type="text/css" />
</div>
<div id="id_js_res">
<script
type="text/javascript" src="/static/js/bokeh-0.12.3.min.js">
</script>
<script
type="text/javascript" src="/static/js/bokeh-widgets-0.12.3.min.js">
</script>
<script async="true" type="text/javascript">
Bokeh.set_log_level("info");
</script>
</div>
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script> <script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
<script> <script>
$(function() { $(function() {
// Get the form fields and hidden div // Get the form fields and hidden div
var checkbox = $("#id_water"); var modality = $("#id_modality");
var hidden = $("#id_waterboattype"); var hidden = $("#id_waterboattype");
@@ -39,15 +20,19 @@
hidden.hide(); hidden.hide();
if (modality.val() == 'water') {
hidden.show();
}
// Setup an event listener for when the state of the // Setup an event listener for when the state of the
// checkbox changes. // checkbox changes.
checkbox.change(function() { modality.change(function() {
// Check to see if the checkbox is checked. // Check to see if the checkbox is checked.
// If it is, show the fields and populate the input. // If it is, show the fields and populate the input.
// If not, hide the fields. // If not, hide the fields.
if (checkbox.is(':checked')) { var Value = modality.val();
if (Value=='water') {
// Show the hidden fields. // Show the hidden fields.
hidden.show(); hidden.show();
} else { } else {
@@ -74,173 +59,63 @@
</script> </script>
<div id="id_css_res">
<link rel="stylesheet" href="/static/css/bokeh-0.12.3.min.css" type="text/css" />
<link rel="stylesheet" href="/static/css/bokeh-widgets-0.12.3.min.css" type="text/css" />
</div>
<div id="id_js_res">
<script
type="text/javascript" src="/static/js/bokeh-0.12.3.min.js">
</script>
<script
type="text/javascript" src="/static/js/bokeh-widgets-0.12.3.min.js">
</script>
</div>
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
<div id="id_script"> <div id="id_script">
</div> </div>
<style> <ul class="main-content">
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
html, body {height: 100%; margin:5px;}
</style>
<li class="grid_4">
<p>Summary for {{ theuser.first_name }} {{ theuser.last_name }}
between {{ startdate|date }} and {{ enddate|date }}</p>
</li>
<div id="title" class="grid_12 alpha"> <li class="grid_4">
<div class="grid_10 alpha"> <div id="id_chart">
&nbsp;
</div>
<div class="grid_2 omega">
{% if user.is_authenticated and user|is_manager %}
<div class="grid_2 alpha dropdown">
<button class="grid_2 alpha button green small dropbtn">
{{ theuser.first_name }} {{ theuser.last_name }}
</button>
<div class="dropdown-content">
{% for member in user|team_members %}
<a class="button green small" href="/rowers/{{ member.id }}/flexall/{{ xparam }}/{{ yparam1 }}/{{ yparam2 }}/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}">{{ member.first_name }} {{ member.last_name }}</a>
{% endfor %}
</div>
{% else %}
&nbsp;
{% endif %}
</div>
</div>
<div class="grid_12 alpha"> {{ the_div|safe }}
<div id="form" class="grid_6 alpha"> </div>
</li>
<li>
<form enctype="multipart/form-data" action="{{ formloc }}" method="post"> <form enctype="multipart/form-data" action="{{ formloc }}" method="post">
{% csrf_token %}
<div class="grid_2 alpha">
<table> <table>
{{ optionsform.as_table }} {{ optionsform.as_table }}
</table> </table>
</div>
<div class="grid_2 suffix_2 omega">
<input type="hidden" name="options" value="options"> <input type="hidden" name="options" value="options">
<input class="grid_1 alpha button green small" value="Submit" type="Submit"> </li>
</div> <li>
</form>
</div>
<div class="grid_6 omega">
<p>Use this form to select a different date range:</p>
<p>
Select start and end date for a date range:
<div class="grid_4 alpha">
<form enctype="multipart/form-data" action="" method="post">
<table> <table>
{{ form.as_table }} {{ form.as_table }}
</table> </table>
</li>
<li>
<table>
{{ flexaxesform.as_table }}
</table>
</li>
<li>
{% csrf_token %} {% csrf_token %}
</div> <input class="button green small" value="Submit" type="Submit">
<div class="grid_2 omega">
<input name='daterange' class="button green" type="submit" value="Submit"> </form>
</div>
<div class="grid_4 alpha">
<form enctype="multipart/form-data" action="" method="post">
Or use the last {{ deltaform }} days.
</div>
<div class="grid_2 omega">
{% csrf_token %}
<input name='datedelta' class="button green" type="submit" value="Submit">
</form> </form>
</div> </li>
</div> </ul>
</div>
<div id="summary" class="grid_6 suffix_6 alpha">
<p>Summary for {{ theuser.first_name }} {{ theuser.last_name }}
between {{ startdate|date }} and {{ enddate|date }}</p>
<div id="plotbuttons" class="grid_6 alpha">
<div class="grid_2 alpha dropdown">
<button class="grid_2 alpha button blue small dropbtn">X-axis</button>
<div class="dropdown-content">
{% for key, value in axchoicesbasic.items %}
{% if key != 'None' %}
<a class="button blue small alpha" href="/rowers/flexall/{{ key }}/{{ yparam1 }}/{{ yparam2 }}/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d"}}">{{ value }}</a>
{% endif %}
{% endfor %}
{% if promember %}
{% for key, value in axchoicespro.items %}
<a class="button blue small alpha" href="/rowers/flexall/{{ key }}/{{ yparam1 }}/{{ yparam2 }}/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d"}}">{{ value }}</a>
{% endfor %}
{% else %}
{% for key, value in axchoicespro.items %}
<a class="button rosy small" href="/rowers/promembership">{{ value }}</a>
{% endfor %}
{% endif %}
</div>
</div>
<div class="grid_2 dropdown">
<button class="grid_2 alpha button blue small dropbtn">Left</button>
<div class="dropdown-content">
{% for key, value in axchoicesbasic.items %}
{% if key not in noylist and key != 'None' %}
<a class="button blue small" href="/rowers/flexall/{{ xparam }}/{{ key }}/{{ yparam2 }}/{{ startdate|date:"Y-m-d"}}/{{ enddate|date:"Y-m-d"}}">{{ value }}</a>
{% endif %}
{% endfor %}
{% if promember %}
{% for key, value in axchoicespro.items %}
{% if key not in noylist %}
<a class="button blue small" href="/rowers/flexall/{{ xparam }}/{{ key }}/{{ yparam2 }}/{{ startdate|date:"Y-m-d"}}/{{ enddate|date:"Y-m-d"}}">{{ value }}</a>
{% endif %}
{% endfor %}
{% else %}
{% for key, value in axchoicespro.items %}
{% if key not in noylist %}
<a class="button rosy small" href="/rowers/promembership">{{ value }} (Pro)</a>
{% endif %}
{% endfor %}
{% endif %}
</div>
</div>
<div class="grid_2 dropdown omega">
<button class="grid_2 alpha button blue small dropbtn">Right</button>
<div class="dropdown-content">
{% for key, value in axchoicesbasic.items %}
{% if key not in noylist %}
<a class="button blue small" href="/rowers/flexall/{{ xparam }}/{{ yparam1 }}/{{ key }}/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d"}}">{{ value }}</a>
{% endif %}
{% endfor %}
{% if promember %}
{% for key, value in axchoicespro.items %}
{% if key not in noylist %}
<a class="button blue small" href="/rowers/flexall/{{ xparam }}/{{ yparam1 }}/{{ key }}/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d"}}">{{ value }}</a>
{% endif %}
{% endfor %}
{% else %}
{% for key, value in axchoicespro.items %}
{% if key not in noylist %}
<a class="button rosy small" href="/rowers/promembership">{{ value }} (Pro)</a>
{% endif %}
{% endfor %}
{% endif %}
</div>
</div>
</div>
<div id="id_chart" class="grid_12 alpha">
{{ the_div|safe }}
</div>
{% endblock %} {% endblock %}
@@ -253,16 +128,25 @@
$(function($) { $(function($) {
console.log('loading script'); console.log('loading script');
$.getJSON(window.location.protocol + '//'+window.location.host + '/rowers/flexalldata', function(json) { $.getJSON(window.location.protocol + '//'+window.location.host + '/rowers/flexalldata', function(json) {
console.log('got script');
var counter=0; var counter=0;
var script = json.script; var script = json.script;
var div = json.div; var div = json.div;
console.log('set vars');
$("#id_sitready").remove(); $("#id_sitready").remove();
console.log('sitready removed');
$("#id_chart").append(div); $("#id_chart").append(div);
console.log(div); console.log('div appended');
$("#id_script").append("<script>"+script+"</s"+"cript>"); $("#id_script").append("<script>"+script+"</s"+"cript>");
console.log('script changed');
}); });
}); });
</script> </script>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_analytics.html' %}
{% endblock %}
+91 -143
View File
@@ -1,17 +1,16 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}Workout Statistics{% endblock %} {% block title %}Rowsandall {% endblock %}
{% block content %}
{% block main %}
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script> <script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
<script> <script>
$(function() { $(function() {
// Get the form fields and hidden div // Get the form fields and hidden div
var checkbox = $("#id_water"); var modality = $("#id_modality");
var hidden = $("#id_waterboattype"); var hidden = $("#id_waterboattype");
@@ -21,14 +20,19 @@
hidden.hide(); hidden.hide();
if (modality.val() == 'water') {
hidden.show();
}
// Setup an event listener for when the state of the // Setup an event listener for when the state of the
// checkbox changes. // checkbox changes.
checkbox.change(function() { modality.change(function() {
// Check to see if the checkbox is checked. // Check to see if the checkbox is checked.
// If it is, show the fields and populate the input. // If it is, show the fields and populate the input.
// If not, hide the fields. // If not, hide the fields.
if (checkbox.is(':checked')) { var Value = modality.val();
if (Value=='water') {
// Show the hidden fields. // Show the hidden fields.
hidden.show(); hidden.show();
} else { } else {
@@ -46,155 +50,80 @@
// $("#hidden_field").val(""); // $("#hidden_field").val("");
} }
}); });
});
});
</script> </script>
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
<script async="true" type="text/javascript"> <div id="id_css_res">
Bokeh.set_log_level("info"); <link rel="stylesheet" href="/static/css/bokeh-0.12.3.min.css" type="text/css" />
</script> <link rel="stylesheet" href="/static/css/bokeh-widgets-0.12.3.min.css" type="text/css" />
{{ plotscript |safe }}
<script>
// Set things up to resize the plot on a window resize. You can play with
// the arguments of resize_width_height() to change the plot's behavior.
var plot_resize_setup = function () {
var plotid = Object.keys(Bokeh.index)[0]; // assume we have just one plot
var plot = Bokeh.index[plotid];
var plotresizer = function() {
// arguments: use width, use height, maintain aspect ratio
plot.resize_width_height(true, true, true);
};
window.addEventListener('resize', plotresizer);
plotresizer();
};
window.addEventListener('load', plot_resize_setup);
</script>
<style>
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
html, body {height: 100%; margin:5px;}
</style>
<div class="grid_12 alpha">
<div class="grid_4 alpha">
{% if theuser %}
<h3>{{ theuser.first_name }}'s Workout Statistics</h3>
{% else %}
<h3>{{ user.first_name }}'s Workout Statistics</h3>
{% endif %}
</div>
<div class="grid_2 suffix_6 omega">
{% if user.is_authenticated and user|is_manager %}
<div class="grid_2 alpha dropdown">
<button class="grid_2 alpha button green small dropbtn">
{{ theuser.first_name }} {{ theuser.last_name }}
</button>
<div class="dropdown-content">
{% for member in user|team_members %}
<a class="button green small" href="/rowers/{{ member.id }}/cumstats/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}/p/{{ plotfield }}">{{ member.first_name }} {{ member.last_name }}</a>
{% endfor %}
</div>
{% else %}
&nbsp;
{% endif %}
</div>
</div> </div>
<div class="grid_12 alpha"> <div id="id_js_res">
<div id="summary" class="grid_6 alpha"> <script
type="text/javascript" src="/static/js/bokeh-0.12.3.min.js">
</script>
<script
type="text/javascript" src="/static/js/bokeh-widgets-0.12.3.min.js">
</script>
</div>
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
<div id="id_script">
</div>
<ul class="main-content">
<li class="grid_4">
<p>Summary for {{ theuser.first_name }} {{ theuser.last_name }} <p>Summary for {{ theuser.first_name }} {{ theuser.last_name }}
between {{ startdate|date }} and {{ enddate|date }}</p> between {{ startdate|date }} and {{ enddate|date }}</p>
</li>
<p>Direct link for other Pro users: <li class="grid_4">
<a href="/rowers/{{ id }}/cumstats/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}/p/{{ plotfield }}">https://rowsandall.com/rowers/{{ id }}/cumstats/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}/p/{{ plotfield }}</a> {% if stats %}
</p> <h2>Statistics</h2>
<form enctype="multipart/form-data" action="{{ formloc }}" method="post">
{% csrf_token %}
<div class="grid_2 alpha">
<table>
{{ optionsform.as_table }}
</table>
</div>
<div class="grid_2 suffix_2 omega">
<input type="hidden" name="options" value="options">
<input class="grid_1 alpha button green small" value="Submit" type="Submit">
</div>
</form>
</div>
<div id="form" class="grid_6 omega">
<p>Use this form to select a different date range:</p>
<p>
Select start and end date for a date range:
<div class="grid_4 alpha">
<form enctype="multipart/form-data" action="" method="post">
<table>
{{ form.as_table }}
</table>
{% csrf_token %}
</div>
<div class="grid_2 omega">
<input name='daterange' class="button green" type="submit" value="Submit"> </form>
</div>
<div class="grid_4 alpha">
<form enctype="multipart/form-data" action="" method="post">
Or use the last {{ deltaform }} days.
</div>
<div class="grid_2 omega">
{% csrf_token %}
<input name='datedelta' class="button green" type="submit" value="Submit">
</form>
</div>
</div>
</div>
<div class="grid_12 alpha">
<div class="grid_4 alpha">
{% if stats %}
{% for key, value in stats.items %}
<h2>{{ value.verbosename }}</h2>
<div class="grid_1">
<p>
<a class="button blue small" href="/rowers/{{ id }}/cumstats/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}/p/{{ key }}">Plot</a>
</p>
</div>
<table width="100%" class="listtable"> <table width="100%" class="listtable">
<thead> <thead>
<tr> <tr>
<th>Metric</th> <th>Metric</th>
<th>Value</th> <th>Mean</th>
<th>Minimum</th>
<th>25&#37;</th>
<th>Median</th>
<th>75&#37;</th>
<th>Maximum</th>
<th>Standard Deviation</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for key, value in stats.items %}
<tr> <tr>
<td>Mean</td><td>{{ value.mean|floatformat:-2 }}</td> <td>{{ value.verbosename }}</td>
</tr><tr> <td>{{ value.mean|floatformat:-2 }}</td>
<td>Minimum</td><td>{{ value.min|floatformat:-2 }}</td> <td>{{ value.min|floatformat:-2 }}</td>
</tr><tr> <td>{{ value.firstq|floatformat:-2 }}</td>
<td>25&#37;</td><td>{{ value.firstq|floatformat:-2 }}</td> <td>{{ value.median|floatformat:-2 }}</td>
</tr><tr> <td>{{ value.thirdq|floatformat:-2 }}</td>
<td>Median</td><td>{{ value.median|floatformat:-2 }}</td> <td>{{ value.max|floatformat:-2 }}</td>
</tr><tr> <td>{{ value.std|floatformat:-2 }}</td>
<td>75&#37;</td><td>{{ value.thirdq|floatformat:-2 }}</td>
</tr><tr>
<td>Maximum</td><td>{{ value.max|floatformat:-2 }}</td>
</tr><tr>
<td>Standard Deviation</td><td>{{ value.std|floatformat:-2 }}</td>
</tr> </tr>
{% endfor %}
</tbody> </tbody>
</table> </table>
{% endfor %}
{% endif %} {% endif %}
</div> </li>
<div class="grid_8 omega"> <li class="grid_4">
{% if cordict %} {% if cordict %}
<div class="grid_8"> <h2> Correlation matrix</h2>
<h2> Correlation Matrix</h2>
<p>This matrix indicates a positive (+) or negative (-) correlation between two parameters. The Spearman correlation coefficient has values between +1 and -1. Positive correlation between two metrics means that if one metric increases, the other value is also likely to increase. Negative is the opposite. The further from zero, the higher the likelyhood. <p>This matrix indicates a positive (+) or negative (-) correlation between two parameters. The Spearman correlation coefficient has values between +1 and -1. Positive correlation between two metrics means that if one metric increases, the other value is also likely to increase. Negative is the opposite. The further from zero, the higher the likelyhood.
</p> </p>
<table width="90%" class="cortable"> <table width="90%" class="cortable">
@@ -229,13 +158,32 @@
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
<div class="grid_8">
{% endif %} {% endif %}
<div class="grid_8"> </li>
{{ plotdiv|safe }} <li>
</div> <form enctype="multipart/form-data" action="{{ formloc }}" method="post">
</div> <table>
</div> {{ optionsform.as_table }}
</table>
<input type="hidden" name="options" value="options">
</li>
<li>
<table>
{{ form.as_table }}
</table>
</li>
<li>
{% csrf_token %}
<input class="button green small" value="Submit" type="Submit">
</form>
</li>
</ul>
{% endblock %}
{% block sidebar %}
{% include 'menu_analytics.html' %}
{% endblock %} {% endblock %}
+46 -44
View File
@@ -1,10 +1,12 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% block title %}About us{% endblock title %} {% block title %}Rowsandall Developers Info{% endblock title %}
{% block content %} {% block main %}
<div class="grid_6 alpha"> <h1>Resources for developers</h1>
<h2>Resources for developers</h2>
<ul class="main-content">
<li class="grid_4">
<p>On this page, a work in progress, I will collect useful information <p>On this page, a work in progress, I will collect useful information
for developers of rowing data apps and hardware.</p> for developers of rowing data apps and hardware.</p>
@@ -14,51 +16,50 @@
related workout data. You can now offer your users easy ways to get related workout data. You can now offer your users easy ways to get
their data on this site.</p> their data on this site.</p>
<p>There are three ways to allow your users to get data to Rowsandall.com.</p> </li>
<h5>File based export from your app</h5> <li class="grid_2">
<p>There are three ways to allow your users to get data to Rowsandall.com.</p>
<h2>File based export from your app</h2>
<p>Enable export of TCX, FIT or CSV formatted files from your app. <p>Enable export of TCX, FIT or CSV formatted files from your app.
The users The users
upload the file to Rowsandall.com.</p> upload the file to Rowsandall.com.</p>
<ul> <ul class="contentli">
<li>Advantages <li>Advantages
<ul> <ul class="contentli">
<li>User sees immediate results</li> <li>User sees immediate results</li>
</ul> </ul>
</li> </li>
<li>Disadvantages <li>Disadvantages
<ul> <ul class="contentli">
<li>It is a multi-step process: Download from your <li>It is a multi-step process: Download from your
app, store, upload.</li> app, store, upload.</li>
</ul> </ul>
</li> </li>
</ul> </ul>
<h2>Email from your app</h2>
<h5>Email from your app</h5>
<p>Similar as above, generate TCX, FIT or CSV formatted files and <p>Similar as above, generate TCX, FIT or CSV formatted files and
email them email them
to <i>workouts@rowsandall.com</i> directly from your app. The From: field to <em>workouts@rowsandall.com</em> directly from your app. The From: field
should be the email address of the registered user.</p> should be the email address of the registered user.</p>
<ul> <ul class="contentli">
<li>Advantages <li>Advantages
<ul> <ul class="contentli">
<li>It's a simple process, which can be automated.</li> <li>It's a simple process, which can be automated.</li>
</ul> </ul>
</li> </li>
<li>Disadvantages <li>Disadvantages
<ul> <ul class="contentli">
<li>It may take up to five minutes for the workout to show up <li>It may take up to five minutes for the workout to show up
on the site.</li> on the site.</li>
</ul> </ul>
</li> </li>
</ul> </ul>
<h2>Using the REST API</h2>
<h5>Using the REST API</h5>
<p>We are building a REST API which will allow you to post and <p>We are building a REST API which will allow you to post and
receive stroke receive stroke
@@ -70,9 +71,9 @@
with questions and/or suggestions. We with questions and/or suggestions. We
will get back to you as soon as possible.</p> will get back to you as soon as possible.</p>
<ul> <ul class="contentli">
<li>Advantages <li>Advantages
<ul> <ul class="contentli">
<li>Once it is set up, this is a one-click operation.</li> <li>Once it is set up, this is a one-click operation.</li>
<li>You can read a user's workout data from the site and use <li>You can read a user's workout data from the site and use
them in your app.</li> them in your app.</li>
@@ -82,7 +83,7 @@
</li> </li>
<li>Disadvantages <li>Disadvantages
<ul> <ul class="contentli">
<li>The API is not stable and not fully tested yet.</li> <li>The API is not stable and not fully tested yet.</li>
<li>You need to register your app with us. We can revoke your <li>You need to register your app with us. We can revoke your
permissions if you misuse them.</li> permissions if you misuse them.</li>
@@ -92,35 +93,31 @@
</li> </li>
</ul> </ul>
</div> </li>
<li class="grid_2">
<div class="grid_6 omega">
<div class="grid_6">
<h2>Quick Links</h2> <h2>Quick Links</h2>
<h5>Accepted file formats</h5> <h3>Accepted file formats</h3>
<p>All files adhering to the standards <a href="http://www8.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd">TCX</a> and <a href="https://www.thisisant.com/resources/fit/">FIT</a> formats will be parsed.</p> <p>All files adhering to the standards <a href="http://www8.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd">TCX</a> and <a href="https://www.thisisant.com/resources/fit/">FIT</a> formats will be parsed.</p>
<p>However, some rowing related parameters are not supported by TCX and FIT. Therefore, we are supporting the CSV format that is documented in the following link.</p> <p>However, some rowing related parameters are not supported by TCX and FIT. Therefore, we are supporting the CSV format that is documented in the following link.</p>
<ul><li><a href="http://rowingdata.readthedocs.io/en/latest/#csv-file-standard">Our standard rowing CSV file</a></li></ul> <ul class="contentli"><li><a href="http://rowingdata.readthedocs.io/en/latest/#csv-file-standard">Our standard rowing CSV file</a></li></ul>
<p>Using this standard will guarantee that your user's data are accepted <p>Using this standard will guarantee that your user's data are accepted
without complaints.</p> without complaints.</p>
<h5>API related documentation</h5> <h2>API related documentation</h2>
<h6>Registering an app</h6> <h3>Registering an app</h3>
<p>We have disabled the self service app link for security reasons. <p>We have disabled the self service app link for security reasons.
We will replace it with a secure self service app link soon. If you We will replace it with a secure self service app link soon. If you
need to register an app, please send email to info@rowsandall.com</p> need to register an app, please send email to info@rowsandall.com</p>
<h6>Authentication</h6> <h3>Authentication</h3>
<p>Standard <a href="https://oauth.net/2/">Oauth2</a> authentication. <p>Standard <a href="https://oauth.net/2/">Oauth2</a> authentication.
Get authorization code by pointing your user to the authorization URL. Get authorization code by pointing your user to the authorization URL.
@@ -128,19 +125,19 @@
expires, expires,
use the refresh token to refresh it.</p> use the refresh token to refresh it.</p>
<p>The redirect URI for user authentication has to be <i>https</i>. <p>The redirect URI for user authentication has to be <em>https</em>.
Developers of iOS or Android apps should contact me directly if Developers of iOS or Android apps should contact me directly if
this doesn't work for them. I can add exceptions.</p> this doesn't work for them. I can add exceptions.</p>
<ul> <ul class="contentli">
<li>Authorization URL: <b>https://{{ request.get_host }}/rowers/o/authorize</b></li> <li>Authorization URL: <b>https://{{ request.get_host }}/rowers/o/authorize</b></li>
<li>Access Token request: <b>https://{{ request.get_host }}/rowers/o/token/</b></li> <li>Access Token request: <b>https://{{ request.get_host }}/rowers/o/token/</b></li>
<li>Access Token refresh: <b>https://{{ request.get_host }}/rowers/o/token/</b></li> <li>Access Token refresh: <b>https://{{ request.get_host }}/rowers/o/token/</b></li>
<li>Handy utility for testing: <b><a href="http://django-oauth-toolkit.herokuapp.com/consumer/">http://django-oauth-toolkit.herokuapp.com/consumer/</a></b></li> <li>Handy utility for testing: <b><a href="http://django-oauth-toolkit.herokuapp.com/consumer/">http://django-oauth-toolkit.herokuapp.com/consumer/</a></b></li>
</ul> </ul>
<h6>API documentation</h6> <h3>API documentation</h3>
<p>Once you have a registered app, you have gone through the authorization <p>Once you have a registered app, you have gone through the authorization
and have successfully obtained an access token, you can use it to place and have successfully obtained an access token, you can use it to place
@@ -149,7 +146,7 @@
<p>The workout summary data and the stroke data are obtained and sent <p>The workout summary data and the stroke data are obtained and sent
separately.</p> separately.</p>
<ul> <ul class="contentli">
<li><a href="/rowers/api-docs">API documentation</a> <li><a href="/rowers/api-docs">API documentation</a>
(But refer to the below for stroke data.)</li> (But refer to the below for stroke data.)</li>
<li><a href="/rowers/api-docs#/workouts">Try out the workout summary API</a></li> <li><a href="/rowers/api-docs#/workouts">Try out the workout summary API</a></li>
@@ -162,7 +159,7 @@
future to enable updating stroke data. Stroke data for workout {id} are future to enable updating stroke data. Stroke data for workout {id} are
posted to:</p> posted to:</p>
<ul> <ul class="contentli">
<li><b>https://{{ request.get_host }}/rowers/api/workouts/{id}/strokedata</b></li> <li><b>https://{{ request.get_host }}/rowers/api/workouts/{id}/strokedata</b></li>
</ul> </ul>
@@ -180,14 +177,14 @@
</pre></p> </pre></p>
<p>Mandatory data fields are:</p> <p>Mandatory data fields are:</p>
<ul> <ul class="contentli">
<li><b>time</b>: Time (milliseconds since workout start)</li> <li><b>time</b>: Time (milliseconds since workout start)</li>
<li><b>distance</b>: Distance (meters)</li> <li><b>distance</b>: Distance (meters)</li>
<li><b>pace</b>: Pace (milliseconds per 500m)</li> <li><b>pace</b>: Pace (milliseconds per 500m)</li>
<li><b>spm</b> Stroke rate (strokes per minute)</li> <li><b>spm</b> Stroke rate (strokes per minute)</li>
</ul> </ul>
<p>Optional data fiels are:</p> <p>Optional data fiels are:</p>
<ul> <ul class="contentli">
<li><b>power</b>: Power (Watt)</li> <li><b>power</b>: Power (Watt)</li>
<li><b>drivelength</b>: Drive length (meters)</li> <li><b>drivelength</b>: Drive length (meters)</li>
<li><b>dragfactor</b>: Drag factor</li> <li><b>dragfactor</b>: Drag factor</li>
@@ -201,7 +198,7 @@
<li><b>catch</b>: Catch angle per Empower oarlock (degrees)</li> <li><b>catch</b>: Catch angle per Empower oarlock (degrees)</li>
<li><b>finish</b>: Finish angle per Empower oarlock (degrees)</li> <li><b>finish</b>: Finish angle per Empower oarlock (degrees)</li>
<li><b>peakforceangle</b>: Peak Force Angle per Empower oarlock (degrees)</li> <li><b>peakforceangle</b>: Peak Force Angle per Empower oarlock (degrees)</li>
<li><b>slip</b>: Wash as defined per Empower oarlock (degrees)</li> <li><b>slip</b>: Slip as defined per Empower oarlock (degrees)</li>
</ul> </ul>
@@ -211,7 +208,12 @@
must have the same number of records. If an optional data field must have the same number of records. If an optional data field
fails a test, its values are silently replaced by zeros.</p> fails a test, its values are silently replaced by zeros.</p>
</div> </li>
</div> </ul>
{% endblock %}
{% block sidebar %}
{% include 'menu_help.html' %}
{% endblock %}
{% endblock content %}
+19 -13
View File
@@ -1,4 +1,4 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
@@ -15,13 +15,15 @@
</script> </script>
{% endblock %} {% endblock %}
{% block content %} {% block main %}
<div id="id_dropregion" class="grid_12 alpha watermark invisible"> <div id="id_main">
<ul class="main-content">
<li class="grid_2">
<div id="id_dropregion" class="watermark invisible">
<p>Drag and drop files here </p> <p>Drag and drop files here </p>
</div> </div>
<div id="id_drop-files" class="grid_12 alpha drop-files"> <div id="id_drop-files" class="drop-files">
<form id="file_form" enctype="multipart/form-data" action="{{ formloc }}" method="post"> <form id="file_form" enctype="multipart/form-data" action="{{ formloc }}" method="post">
<div id="left" class="grid_6 alpha">
<h1>Upload Workout File</h1> <h1>Upload Workout File</h1>
{% if user.is_authenticated and user|is_manager %} {% if user.is_authenticated and user|is_manager %}
<p>Looking for <a href="/rowers/workout/upload/team/">Team Manager <p>Looking for <a href="/rowers/workout/upload/team/">Team Manager
@@ -37,13 +39,11 @@
{{ form.as_table }} {{ form.as_table }}
</table> </table>
{% csrf_token %} {% csrf_token %}
<div id="formbutton" class="grid_1 prefix_4 suffix_1">
<input class="button green" type="submit" value="Submit"> <input class="button green" type="submit" value="Submit">
</div> </div>
</li>
</div> <li class="grid_2">
<div id="right" class="grid_6 omega">
<h1>Optional extra actions</h1> <h1>Optional extra actions</h1>
<p> <p>
<table> <table>
@@ -67,12 +67,13 @@
<p><b>Select Files with the File button or drag them on the marked area</b></p> <p><b>Select Files with the File button or drag them on the marked area</b></p>
</div> </li>
</form> </form>
</div> </ul>
</div>
{% endblock %} {% endblock %}
{% block scripts %} {% block scripts %}
@@ -221,8 +222,8 @@ $('#id_workouttype').change();
console.log(value); console.log(value);
}); });
$("#id_drop-files").replaceWith( $("#id_main").replaceWith(
'<div id="id_waiting"><img src="/static/img/rowingtimer.gif" width="120" height="100">' '<div id="id_waiting"><img src="/static/img/rowingtimer.gif" width="120" height="100" style="width:120px">'
); );
$.ajax({ $.ajax({
data: data, data: data,
@@ -310,3 +311,8 @@ $('#id_workouttype').change();
}; };
</script> </script>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_workouts.html' %}
{% endblock %}
+56 -43
View File
@@ -1,9 +1,10 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% block title %}Contact Us{% endblock title %} {% block title %}Contact Us{% endblock title %}
{% block content %} {% block main %}
<div id="emailform" class="grid_6 alpha"> <h1>Contact us through email</h1>
<h1>Contact us through email</h1>
<ul class="main-content">
<li class="grid_2">
{% if form.errors %} {% if form.errors %}
<p style="color: red;"> <p style="color: red;">
Please correct the error{{ form.errors|pluralize }} below. Please correct the error{{ form.errors|pluralize }} below.
@@ -23,28 +24,28 @@
<tr><td> <tr><td>
</span> </span>
<span class="span"> <span class="span">
</td><td> </td><td>
<input name= "lastname" class="inputtext" maxlength="255" size="18" /> <input name= "lastname" class="inputtext" maxlength="255" size="18" />
<label class="spanlabel">Last</label> <label class="spanlabel">Last</label>
</span> </span>
</td></tr> </td></tr>
<tr><td> <tr><td>
<label class="label">Email Address <span class="required">*</span></label> <label class="label">Email Address <span class="required">*</span></label>
</td><td> </td><td>
<input name="email" class="inputtext" type="text" maxlength="255" size="35" /> <input name="email" class="inputtext" type="text" maxlength="255" size="35" />
</td></tr> </td></tr>
<tr><td> <tr><td>
<label class="label">Subject <span class="required">*</span></label> <label class="label">Subject <span class="required">*</span></label>
</td><td> </td><td>
<input name="subject" class="inputtext" type="text" maxlength="255" size="45" /> <input name="subject" class="inputtext" type="text" maxlength="255" size="45" />
</td></tr> </td></tr>
</table> </table>
<label class="label">You must answer <u>YES</u> to the question below to approve sending this email. <span class="required">*</span></label> <label class="label">You must answer <u>YES</u> to the question below to approve sending this email. <span class="required">*</span></label>
<table> <table>
<tr><td> <tr><td>
Do you want to send me an email? Do you want to send me an email?
</td><td> </td><td>
<input name="botcheck" class="inputtext" type="text" maxlength="5" size="5" /> <input name="botcheck" class="inputtext" type="text" maxlength="5" size="5" />
</td></tr> </td></tr>
<tr><td> <tr><td>
<label class="label">Message <span class="required">*</span></label> <label class="label">Message <span class="required">*</span></label>
@@ -54,40 +55,46 @@
<tr><td> <tr><td>
<input class="button green" type="submit" name="submitform" value="Send Message" /> <input class="button green" type="submit" name="submitform" value="Send Message" />
</td></tr> </td></tr>
</table> </table>
</form> </form>
</div> </li>
<div class="grid_6 omega"> <li class="grid_2">
<h1>Bug reporting, feature requests</h1> <h1>Bug reporting, feature requests</h1>
<p> <p>
Bug reports and feature requests can be done through our BitBucket page. Please check on the following link if your bug or issue is a known one. Feel free to file any feature request. Bug reports and feature requests can be done through our BitBucket page. Please check on the following link if your bug or issue is a known one. Feel free to file any feature request.
<ul> <ul>
<li><a href="https://bitbucket.org/sanderroosendaal/rowsandall/issues">BitBucket Issue list (click here to go report an issue or request a feature)</a></li> <li><a href="https://bitbucket.org/sanderroosendaal/rowsandall/issues">BitBucket Issue list (click here to go report an issue or request a feature)</a></li>
</ul> </ul>
</p> </p>
</li>
<h1>Facebook Group</h1> <li class="grid_2">
<h1>Facebook Group</h1>
<p>We run a facebook group where you can post questions and report problems, <p>We run a facebook group where you can post questions and report problems,
especially if you think the wider user community benefits from the answers.</p> especially if you think the wider user community benefits from the answers.</p>
<ul> <ul>
<li><a href="https://www.facebook.com/groups/rowsandall/">https://www.facebook.com/groups/rowsandall/</a></li> <li><a href="https://www.facebook.com/groups/rowsandall/">https://www.facebook.com/groups/rowsandall/</a></li>
</ul> </ul>
</li>
<h1>Twitter</h1> <li class="grid_2">
<h1>Twitter</h1>
<p>You can also check me on Twitter: <p>You can also check me on Twitter:
<ul> <ul>
<li><a href="https://twitter.com/rowsandall">https://twitter.com/rowsandall</a> <li><a href="https://twitter.com/rowsandall">https://twitter.com/rowsandall</a>
</ul> </ul>
When the site is down, this is the appropriate channel to look for apologies, updates, and offer help. When the site is down, this is the appropriate channel to look for apologies, updates, and offer help.
</p> </p>
</li>
<h1>Rowsandall s.r.o.</h1> <li class="grid_2">
<h1>Rowsandall s.r.o.</h1>
<p><strong>Rowsandall s.r.o.</strong><br /> <p><strong>Rowsandall s.r.o.</strong><br />
Nov&eacute; sady 988/2<br /> Nov&eacute; sady 988/2<br />
602 00 Brno<br /> 602 00 Brno<br />
Czech Republic<br /> Czech Republic<br />
@@ -97,8 +104,14 @@ When the site is down, this is the appropriate channel to look for apologies, up
Email: <a href="mailto:info@rowsandall.com">info@rowsandall.com</a><br /> Email: <a href="mailto:info@rowsandall.com">info@rowsandall.com</a><br />
The company is registered in the business register at the The company is registered in the business register at the
Regional Court in Brno (Společnost je zapsána v obchodním rejstříku vedeném u Krajského soudu v Brně, oddíl C, vložka 105845)<br/> Regional Court in Brno (Společnost je zapsána v obchodním rejstříku vedeném u Krajského soudu v Brně, oddíl C, vložka 105845)<br/>
</p> </p>
</li>
</ul>
{% endblock %}
{% block sidebar %}
{% include 'menu_help.html' %}
{% endblock %}
</div>
{% endblock content %}
+41 -49
View File
@@ -1,10 +1,10 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}Workouts{% endblock %} {% block title %}Empower FIX{% endblock %}
{% block content %} {% block main %}
<script> <script>
function toggle(source) { function toggle(source) {
@@ -65,11 +65,22 @@
</script> </script>
<div class="grid_12 alpha"> <h1>Empower Workouts</h1>
{% include "teambuttons.html" with teamid=team.id team=team %}
</div> <ul class="main-content">
<div class="grid_12 alpha"> <li class="grid_2">
<h2>Empower Workouts</h2> <p>Use the date form to reduce the selection</p>
<p>
<form enctype="multipart/form-data" action="" method="post">
<table>
{{ dateform.as_table }}
</table>
{% csrf_token %}
<input name='daterange' class="green button" type="submit" value="Submit">
</form>
</p>
</li>
<li class="grid_2">
<p>This functionality is aimed at users who have uploaded workouts from <p>This functionality is aimed at users who have uploaded workouts from
the Nielsen-Kellerman Empower Oarlock/SpeedCoach combination before the the Nielsen-Kellerman Empower Oarlock/SpeedCoach combination before the
power inflation bug was known (May 4, 2018). </p> power inflation bug was known (May 4, 2018). </p>
@@ -87,32 +98,11 @@
<p> <p>
You can use this page to correct those workouts. You can use this page to correct those workouts.
</p> </p>
</li>
<li class="grid_4">
</div> <p>
<div class="grid_12 alpha">
<div class="grid_6 alpha">
<form enctype="multipart/form-data" action="" method="post"> <form enctype="multipart/form-data" action="" method="post">
<div class="grid_4 alpha">
<table>
{{ dateform.as_table }}
</table>
{% csrf_token %}
</div>
<div class="grid_2 omega">
<input name='daterange' class="button green" type="submit" value="Submit">
</div>
</form>
</div>
</div>
<form enctype="multipart/form-data" action="" method="post">
<div id="workouts_table" class="grid_8 alpha">
{% if workouts %} {% if workouts %}
<input type="checkbox" onClick="toggle(this)" /> Toggle All<br/> <input type="checkbox" onClick="toggle(this)" /> Toggle All<br/>
@@ -120,25 +110,27 @@
<table width="100%" class="listtable"> <table width="100%" class="listtable">
{{ form.as_table }} {{ form.as_table }}
</table> </table>
{% else %}
<p> No workouts found </p>
{% endif %}
</div>
<div id="form_settings" class="grid_4 alpha">
<p>Select workouts on the left,
and press submit</p>
<div class="grid_1 prefix_2 suffix_1">
<p>
{% csrf_token %} {% csrf_token %}
<input name='workoutselectform' class="button green" type="submit" value="Submit"> <input name='workoutselectform' class="button green" type="submit" value="Submit">
</p>
</div>
<div class="grid_4">
<p>You can use the date form above to reduce the selection</p>
</div>
</div>
</form>
</form>
</p>
{% else %}
<p> No workouts found </p>
{% endif %}
</li>
{% if workouts %}
<li>
<p>Select workouts
and press submit
</p>
</li>
{% endif %}
</ul>
{% endblock %}
{% block sidebar %}
{% include 'menu_workouts.html' %}
{% endblock %} {% endblock %}
+16 -11
View File
@@ -1,23 +1,24 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}Rowsandall Workouts Summary Export{% endblock %} {% block title %}Rowsandall Workouts Summary Export{% endblock %}
{% block content %} {% block main %}
<div class="grid_12"> <h1>Export all workouts</h1>
<ul class="main-content">
<li class="grid_2">
<p>
<form enctype="multipart/form-data" method="post"> <form enctype="multipart/form-data" method="post">
<div class="grid_4 alpha">
<table> <table>
{{ form.as_table }} {{ form.as_table }}
</table> </table>
{% csrf_token %} {% csrf_token %}
</div> <input class="green button" type="submit" value="Submit">
<div class="grid_2">
<input class="button green" type="submit" value="Submit">
</div>
</form> </form>
<div class="grid_6 omega"> </p>
</li>
<li class="grid_2">
<p> <p>
With this form, you can export a summary table for all workouts within a selected date range. With this form, you can export a summary table for all workouts within a selected date range.
The table will be sent to you as a CSV file which can be opened in excel. The table contains The table will be sent to you as a CSV file which can be opened in excel. The table contains
@@ -27,7 +28,11 @@
By setting the start date to your registration date or earlier and the end date to today, By setting the start date to your registration date or earlier and the end date to today,
you will receive all workout data we are storing for you. you will receive all workout data we are storing for you.
</p> </p>
</div> </li>
</div> </ul>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_profile.html' %}
{% endblock %}
+19 -14
View File
@@ -1,41 +1,46 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% block title %}Change Favorite Charts{% endblock %} {% block title %}Change Favorite Charts{% endblock %}
{% block content %} {% block main %}
<h1>Change Favorite Charts of {{ rower.user.first_name }} {{ rower.user.last_name }}</h1>
<form method="post"> <form method="post">
<ul class="main-content">
{% csrf_token %} {% csrf_token %}
<div class="grid_12 alpha"> <li class="grid_4">
<div class="grid_4 alpha fav-form-header"> <div class="fav-form-header">
<p><input type="submit" value="Update Favorites" class="button green small"/></p> <p><input type="submit" value="Update Favorites" class="button green small"/></p>
</div> </div>
</div>
{{ favorites_formset.management_form }} {{ favorites_formset.management_form }}
</li>
{% for favorites_form in favorites_formset %} {% for favorites_form in favorites_formset %}
<div class="fav-formset grid_4 alpha"> <li>
<div class="fav-formset rounder">
<h2>Chart {{ forloop.counter }}</h2> <h2>Chart {{ forloop.counter }}</h2>
<table> <table width=100%>
{{ favorites_form.as_table }} {{ favorites_form.as_table }}
</table> </table>
</div> </div>
</li>
{% endfor %} {% endfor %}
<div class="grid_12 alpha"> </ul>
<p>&nbsp;</p>
</div>
</form> </form>
<!-- Include formset plugin - including jQuery dependency --> <!-- Include formset plugin - including jQuery dependency -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="/static/js/jquery.formset.js"></script> <script src="/static/js/jquery.formset.js"></script>
<script> <script>
$('.fav-formset').formset({ $('.fav-formset').formset({
addText: '<div class="grid_12">&nbsp;</div><div class="button grid_2 green small">add chart</div>', addText: '<div>&nbsp;</div><div class="button green small">add chart</div>',
deleteText: '<div class="grid_12"><p>&nbsp;</p></div><div class="button grid_1 red small">remove</div>' deleteText: '<div><p>&nbsp;</p></div><div class="button red small">remove</div>'
}); });
</script> </script>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_profile.html' %}
{% endblock %}
+21 -43
View File
@@ -1,10 +1,10 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}Rowsandall Fitness Progress {% endblock %} {% block title %}Rowsandall Fitness Progress {% endblock %}
{% block content %} {% block main %}
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script> <script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
<script> <script>
$(function() { $(function() {
@@ -70,56 +70,34 @@
}; };
window.addEventListener('load', plot_resize_setup); window.addEventListener('load', plot_resize_setup);
</script> </script>
<style>
/* Need this to get the page in "desktop mode"; not having an infinite height.*/ {% if rower.user %}
html, body {height: 100%; margin:5px;} <h1>{{ rower.user.first_name }} Power Estimates</h1>
</style> {% else %}
<h1>{{ user.first_name }} Power Estimates</h1>
{% endif %}
<div id="title" class="grid_12 alpha"> <ul class="main-content">
<div class="grid_6 suffix_6 alpha"> <li class="grid_4">
<form enctype="multipart/form-data" method="post"> {{ the_div|safe }}
</li>
<li class="grid_2">
<form enctype="multipart/form-data" action="/rowers/fitness-progress/user/{{ rower.user.id }}" method="post">
<table> <table>
{{ form.as_table }} {{ form.as_table }}
</table> </table>
{% csrf_token %} {% csrf_token %}
<div class="grid_2 prefix_4 alpha">
<input name='daterange' class="button green" type="submit" value="Submit"> <input name='daterange' class="button green" type="submit" value="Submit">
</div>
</form> </form>
</div>
<div class="grid_10 alpha"> </li>
{% if therower.user %} </ul>
<h3>{{ therower.user.first_name }} Power Estimates</h3>
{% else %}
<h3>{{ user.first_name }} Power Estimates</h3>
{% endif %}
</div>
<div class="grid_2 omega">
{% if user.is_authenticated and user|is_manager %}
<div class="grid_2 alpha dropdown">
<button class="grid_2 alpha button green small dropbtn">
{{ therower.user.first_name }} {{ therower.user.last_name }}
</button>
<div class="dropdown-content">
{% for member in user|team_members %}
<a class="button green small"
href="/rowers/fitness-progress/rower/{{ member.id }}/{{ mode }}">{{ member.first_name }} {{ member.last_name }}</a>
{% endfor %}
</div>
{% else %}
&nbsp;
</div>
{% endif %}
</div>
</div>
<div id="graph" class="grid_12 alpha">
{{ the_div|safe }}
</div>
{% endblock %}
{% block sidebar %}
{% include 'menu_analytics.html' %}
{% endblock %} {% endblock %}
+53 -199
View File
@@ -1,4 +1,4 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% load tz %} {% load tz %}
@@ -6,7 +6,7 @@
{% block title %} Flexible Plot {% endblock %} {% block title %} Flexible Plot {% endblock %}
{% localtime on %} {% localtime on %}
{% block content %} {% block main %}
{{ js_res | safe }} {{ js_res | safe }}
{{ css_res| safe }} {{ css_res| safe }}
@@ -20,197 +20,45 @@
{{ the_script |safe }} {{ the_script |safe }}
<style> <h1>Flexible Chart</h1>
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
html, body {height: 100%; margin:5px;}
</style>
<div id="navigation" class="grid_12 alpha">
{% if user.is_authenticated and mayedit %}
<div class="grid_2 alpha">
<p>
<a class="button gray small" href="/rowers/workout/{{ id }}/edit">Edit Workout</a>
</p>
</div>
<div class="grid_2">
<p>
<a class="button gray small" href="/rowers/workout/{{ id }}/workflow">Workflow View</a>
</p>
</div>
<div class="grid_2 suffix_6 omega">
<p>
<a class="button gray small" href="/rowers/workout/{{ id }}/advanced">Advanced Edit</a>
</p>
</div>
{% endif %}
</div>
<p>&nbsp;</p>
<div id="plotbuttons" class="grid_12 alpha">
<div id="x-axis" class="grid_9 alpha">
<div class="grid_3 alpha dropdown">
<button class="grid_2 alpha button blue small dropbtn">X-axis</button>
<div class="dropdown-content">
<div style="float: left; width:67%;">
{% for key, value in axchoicesbasic.items %}
{% if key != 'None' %}
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/{{ key }}/{{ yparam1 }}/{{ yparam2 }}/{{ plottype }}">{{ value }}</a>
{% endif %}
{% endfor %}
{% if promember %}
{% for key, value in axchoicespro.items %}
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/{{ key }}/{{ yparam1 }}/{{ yparam2 }}/scatter">{{ value }}</a>
{% endfor %}
{% else %}
{% for key, value in axchoicespro.items %}
<a class="button rosy small" href="/rowers/promembership">{{ value }}</a>
{% endfor %}
{% endif %}
</div>
<div style="float: right; width: 33%;">
{% if promember %}
{% for key, value in extrametrics.items %}
<a class="button orange small" href="/rowers/workout/{{ id }}/flexchart/{{ key }}/{{ yparam1 }}/{{ yparam2 }}/{{ plottype }}">{{ value }}</a>
{% endfor %}
{% else %}
{% for key, value in extrametrics.items %}
<a class="button rosy small" href="/rowers/promembership">{{ value }} (Pro)</a>
{% endfor %}
{% endif %}
</div>
</div>
</div>
<div id="left-y" class="grid_3 dropdown">
<button class="grid_2 alpha button blue small dropbtn">Left</button>
<div class="dropdown-content">
<div style="float: left; width:67%;">
{% for key, value in axchoicesbasic.items %}
{% if key not in noylist and key != 'None' %}
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ key }}/{{ yparam2 }}/{{ plottype }}">{{ value }}</a>
{% endif %}
{% endfor %}
{% if promember %}
{% for key, value in axchoicespro.items %}
{% if key not in noylist %}
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ key }}/{{ yparam2 }}/{{ plottype }}">{{ value }}</a>
{% endif %}
{% endfor %}
{% else %}
{% for key, value in axchoicespro.items %}
{% if key not in noylist %}
<a class="button rosy small" href="/rowers/promembership">{{ value }} (Pro)</a>
{% endif %}
{% endfor %}
{% endif %}
</div>
<div style="float: right; width:33%;">
{% if promember %}
{% for key, value in extrametrics.items %}
<a class="button orange small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ key }}/{{ yparam2 }}/{{ plottype }}">{{ value }}</a>
{% endfor %}
{% else %}
{% for key, value in extrametrics.items %}
<a class="button rosy small" href="/rowers/promembership">{{ value }} (Pro)</a>
{% endfor %}
{% endif %}
</div>
</div>
</div>
<div id="right-y" class="grid_3 dropdown omega">
<button class="grid_2 alpha button blue small dropbtn">Right</button>
<div class="dropdown-content">
<div style="float: left; width:67%;">
{% for key, value in axchoicesbasic.items %}
{% if key not in noylist %}
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/{{ key }}/{{ plottype }}">{{ value }}</a>
{% endif %}
{% endfor %}
{% if promember %}
{% for key, value in axchoicespro.items %}
{% if key not in noylist %}
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/{{ key }}/{{ plottype }}">{{ value }}</a>
{% endif %}
{% endfor %}
{% else %}
{% for key, value in axchoicespro.items %}
{% if key not in noylist %}
<a class="button rosy small" href="/rowers/promembership">{{ value }} (Pro)</a>
{% endif %}
{% endfor %}
{% endif %}
</div>
<div style="float: right; width:33%;">
{% if promember %}
{% for key, value in extrametrics.items %}
<a class="button orange small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/{{ key }}/{{ plottype }}">{{ value }}</a>
{% endfor %}
{% else %}
{% for key, value in extrametrics.items %}
<a class="button rosy small" href="/rowers/promembership">{{ value }} (Pro)</a>
{% endfor %}
{% endif %}
</div>
</div>
</div>
</div>
<div id="y-axis" class="grid_3 omega">
<div class="grid_2 alpha tooltip">
<form enctype="multipart/form-data" action="{{ formloc }}" method="post">
{% csrf_token %}
{% if workstrokesonly %}
<input type="hidden" name="workstrokesonly" value="True">
<input class="grid_2 alpha button blue small" value="Remove Rest Strokes" type="Submit">
{% else %}
<input class="grid_2 alpha button blue small" type="hidden" name="workstrokesonly" value="False">
<input class="grid_2 alpha button blue small" value="Include Rest Strokes" type="Submit">
{% endif %}
</form>
<span class="tooltiptext">If your data source allows, this will show or hide strokes taken during rest intervals.</span>
</div>
<div class="grid_1 omega">
{% if plottype == 'scatter' %}
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/{{ yparam2 }}/line">Line</a>
{% else %}
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/{{ yparam2 }}/scatter">Scatter</a>
{% endif %}
</div>
</div>
</div>
<div id="theplot" class="grid_12 alpha">
<ul class="main-content">
<li class="grid_4">
<div id="theplot" class="flexplot">
{{ the_div|safe }} {{ the_div|safe }}
</div>
<div id="favorites" class="grid_12 alpha">
<div class="grid_2 suffix_4 alpha">
{% if maxfav >= 0 %}
<a class="button gray small" href="/rowers/me/favoritecharts">Manage Favorites</a>
{% else %}
&nbsp;
{% endif %}
</div> </div>
<div class="grid_1"> </li>
{% if favoritenr > 0 %} <li class="grid_2">
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart?favoritechart={{ favoritenr|add:-1 }}">&lt</a> <form enctype="multipart/form-data"
{% else %} action=""
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart?favoritechart={{ maxfav }}">&lt</a> method="post">
{% endif %} {% csrf_token %}
</div> <table>
<div class="grid_2"> {{ chartform.as_table }}
</table>
<table>
{{ optionsform.as_table }}
</table>
<p>
<input name="chartform" class="button green" type="submit"
value="Submit">
</p>
</form>
</li>
<li class="grid_2">
<form enctype="multipart/form-data" action="{{ formloc }}" method="post"> <form enctype="multipart/form-data" action="{{ formloc }}" method="post">
{% if favoritenr > 0 %}
<a class="wh"
href="/rowers/workout/{{ id }}/flexchart?favoritechart={{ favoritenr|add:-1 }}">
<i class="fas fa-arrow-alt-left"></i>
</a>
{% else %}
<a class="wh"
href="/rowers/workout/{{ id }}/flexchart?favoritechart={{ maxfav }}">
<i class="fas fa-arrow-alt-left"></i>
</a>
{% endif %}
{% csrf_token %} {% csrf_token %}
<input class="grid_2 alpha button blue small" type="hidden" name="savefavorite" value="True"> <input class="grid_2 alpha button blue small" type="hidden" name="savefavorite" value="True">
{% if workstrokesonly %} {% if workstrokesonly %}
@@ -218,22 +66,28 @@
{% else %} {% else %}
<input type="hidden" name="workstrokesonlysave" value="True"> <input type="hidden" name="workstrokesonlysave" value="True">
{% endif %} {% endif %}
<input class="grid_2 alpha button blue small" value="Make Favorite" type="Submit"> <input value="Make Favorite" type="Submit">
</form>
</div>
<div class="grid_1">
{% if favoritenr < maxfav %} {% if favoritenr < maxfav %}
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart?favoritechart={{ favoritenr|add:1 }}">&gt</a> <a class="wh"
href="/rowers/workout/{{ id }}/flexchart?favoritechart={{ favoritenr|add:1 }}">
<i class="fas fa-arrow-alt-right"></i>
</a>
{% else %} {% else %}
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart?favoritechart=0">&gt</a> <a class="wh"
href="/rowers/workout/{{ id }}/flexchart?favoritechart=0">
<i class="fas fa-arrow-alt-right"></i>
</a>
{% endif %} {% endif %}
</div> </form>
{% if favoritechartnotes %} {% if favoritechartnotes %}
<div class="grid_6 prefix_6 alpha">
<p>Chart {{ favoritenr|add:1 }}:{{ favoritechartnotes }}</p> <p>Chart {{ favoritenr|add:1 }}:{{ favoritechartnotes }}</p>
</div>
{% endif %} {% endif %}
</div> </li>
</ul>
{% endblock %} {% endblock %}
{% endlocaltime %} {% endlocaltime %}
{% block sidebar %}
{% include 'menu_workout.html' %}
{% endblock %}
+3 -4
View File
@@ -1,9 +1,8 @@
<h2>Flex Charts</h2> <h2>Flex Charts</h2>
<div id="id_thumbscripts"> <div id="id_thumbscripts">
</div> </div>
<div id="id_thumbs"> <ul class="main-content" id="id_thumbs">
{{ charts | safe }} {{ charts| safe }}
</div> </ul>
+18 -38
View File
@@ -1,4 +1,4 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% load tz %} {% load tz %}
@@ -6,7 +6,7 @@
{% block title %} Force Curve Plot {% endblock %} {% block title %} Force Curve Plot {% endblock %}
{% localtime on %} {% localtime on %}
{% block content %} {% block main %}
{{ js_res | safe }} {{ js_res | safe }}
{{ css_res| safe }} {{ css_res| safe }}
@@ -19,54 +19,34 @@
{{ the_script |safe }} {{ the_script |safe }}
<h1>Empower Force Curve</h1>
<style> <ul class="main-content">
/* Need this to get the page in "desktop mode"; not having an infinite height.*/ <li class="grid_4">
html, body {height: 100%; margin:5px;}
</style>
<div id="navigation" class="grid_12 alpha">
{% if user.is_authenticated and mayedit %} {% if user.is_authenticated and mayedit %}
<div class="grid_2 alpha">
<p>
<a class="button gray small" href="/rowers/workout/{{ id }}/edit">Edit Workout</a>
</p>
</div>
<div class="grid_2 suffix_2">
<p>
<a class="button gray small" href="/rowers/workout/{{ id }}/advanced">Advanced Edit</a>
</p>
</div>
{% endif %}
<div class="grid_2 suffix_4 omega tooltip">
<form enctype="multipart/form-data" action="{{ formloc }}" method="post"> <form enctype="multipart/form-data" action="{{ formloc }}" method="post">
{% csrf_token %} {% csrf_token %}
{% if workstrokesonly %} {% if workstrokesonly %}
<input type="hidden" name="workstrokesonly" value="True"> <input type="hidden" name="workstrokesonly" value="True">
<input class="grid_2 alpha button blue small" value="Remove Rest Strokes" type="Submit"> <input class="button blue small" value="Remove Rest Strokes" type="Submit">
{% else %} {% else %}
<input class="grid_2 alpha button blue small" type="hidden" name="workstrokesonly" value="False"> <input class="button blue small" type="hidden" name="workstrokesonly" value="False">
<input class="grid_2 alpha button blue small" value="Include Rest Strokes" type="Submit"> <input class="button blue small" value="Include Rest Strokes" type="Submit">
{% endif %}
</form> </form>
{% endif %}
<span class="tooltiptext">If your data source allows, this will show or hide strokes taken during rest intervals.</span> <span class="tooltiptext">If your data source allows, this will show or hide strokes taken during rest intervals.</span>
</div> {% endif %}
</li>
</div> <li class="grid_4">
<p>&nbsp;</p>
<div id="theplot" class="grid_12 alpha">
{{ the_div|safe }} {{ the_div|safe }}
</div> </li>
</ul>
{% endblock %} {% endblock %}
{% endlocaltime %} {% endlocaltime %}
{% block sidebar %}
{% include 'menu_workout.html' %}
{% endblock %}
+26 -22
View File
@@ -1,17 +1,29 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}Workouts{% endblock %} {% block title %}Workouts{% endblock %}
{% block content %} {% block main %}
<div class="grid_12 alpha"> <h1>Fusion Editor</h1>
<h3>Fusion Editor</h3> <ul class="main-content">
</div> <li class="grid_2">
<div class="grid_12 alpha">
<div class="grid_6 alpha"> <form enctype="multipart/form-data" action="" method="post">
<p>
<table>
{{ form.as_table }}
</table>
</p>
<p>
{% csrf_token %}
<input name='fusion' class="button green" type="submit" value="Submit">
</p>
</form>
</li>
<li class="grid_2">
<p> <p>
Adding sensor data from workout {{ workout2.id }} into workout {{ workout1.id }}. Adding sensor data from workout {{ workout2.id }} into workout {{ workout1.id }}.
This will create a new workout. After you submit the form, you will be This will create a new workout. After you submit the form, you will be
@@ -24,21 +36,13 @@
<p> <p>
Workout 2: {{ workout2.name }} Workout 2: {{ workout2.name }}
</p> </p>
<p>On the right hand side, please select the columns from workout 2 that <p>Please select the columns from workout 2 that
you want to replace the equivalent columns in workout 1. </p> you want to replace the equivalent columns in workout 1. </p>
</div> </li>
<div class="grid_4"> </ul>
<form enctype="multipart/form-data" action="" method="post">
<table>
{{ form.as_table }}
</table>
{% csrf_token %}
</div>
<div class="grid_2 omega">
<input name='fusion' class="button green" type="submit" value="Submit"> </form>
</div>
</div>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_workout.html' %}
{% endblock %}
+63 -39
View File
@@ -1,13 +1,13 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}Workouts{% endblock %} {% block title %}Workouts{% endblock %}
{% block content %} {% block main %}
<div id="workouts" class="grid_4 alpha"> <h1>Workout {{ id }} Sensor Fusion</h1>
<div class="grid_4 alpha"> <ul class="main-content">
<h1>Workout {{ id }}</h1> <li>
<table width=100%> <table width=100%>
<tr> <tr>
<th>Rower:</th><td>{{ first_name }} {{ last_name }}</td> <th>Rower:</th><td>{{ first_name }} {{ last_name }}</td>
@@ -29,8 +29,6 @@
<th>Weight Category:</th><td>{{ workout.weightcategory }}</td> <th>Weight Category:</th><td>{{ workout.weightcategory }}</td>
</tr> </tr>
</table> </table>
</div>
<div class="grid_4 alpha">
<p> <p>
<form id="searchform" action="" <form id="searchform" action=""
method="get" accept-charset="utf-8"> method="get" accept-charset="utf-8">
@@ -40,29 +38,66 @@
<input class="searchfield" id="searchbox" name="q" type="text" placeholder="Search"> <input class="searchfield" id="searchbox" name="q" type="text" placeholder="Search">
</form> </form>
</p> </p>
</div> <p>
Select start and end date for a date range: Select start and end date for a date range:
<div class="grid_4 alpha"> </p>
<p> <p>
<form enctype="multipart/form-data" action="/rowers/workout/fusion/{{ id }}/" method="post"> <form enctype="multipart/form-data" action="/rowers/workout/fusion/{{ id }}/" method="post">
<table> <table>
{{ dateform.as_table }} {{ dateform.as_table }}
</table> </table>
{% csrf_token %} {% csrf_token %}
</div>
<div class="grid_2 suffix_2 omega">
<input name='daterange' class="button green" type="submit" value="Submit"> </form>
</p> </p>
</div> <input name='daterange' class="button green" type="submit" value="Submit"> </form>
</li>
<li class="grid_3">
</div> <h1>Fuse this workout with data from:</h1>
<div id="fusion" class="grid_8 omega">
<h1>Fuse this workout with data from:</h1>
{% if workouts %} {% if workouts %}
<p>
<span>
{% if workouts.has_previous %}
{% if request.GET.q %}
<a class="wh" href="?page=1&q={{ request.GET.q }}">
<i class="fas fa-arrow-alt-to-left"></i>
</a>
<a class="wh" href="?page={{ workouts.previous_page_number }}&q={{ request.GET.q }}">
<i class="fas fa-arrow-alt-left"></i>
</a>
{% else %}
<a class="wh" href="?page=1">
<i class="fas fa-arrow-alt-to-left"></i>
</a>
<a class="wh" href="?page={{ workouts.previous_page_number }}">
<i class="fas fa-arrow-alt-left"></i>
</a>
{% endif %}
{% endif %}
<span>
Page {{ workouts.number }} of {{ workouts.paginator.num_pages }}.
</span>
{% if workouts.has_next %}
{% if request.GET.q %}
<a class="wh" href="?page={{ workouts.next_page_number }}&q={{ request.GET.q }}">
<i class="fas fa-arrow-alt-right"></i>
</a>
<a class="wh" href="?page={{ workouts.paginator.num_pages }}&q={{ request.GET.q }}">
<i class="fas fa-arrow-alt-to-right">
</a>
{% else %}
<a class="wh" href="?page={{ workouts.next_page_number }}">
<i class="fas fa-arrow-alt-right"></i>
</a>
<a class="wh" href="?page={{ workouts.paginator.num_pages }}">
<i class="fas fa-arrow-alt-to-right"></i>
</a>
{% endif %}
{% endif %}
</span>
</p>
<table width="100%" class="listtable"> <table width="100%" class="listtable">
<thead> <thead>
<tr> <tr>
@@ -77,7 +112,7 @@
<th> Fusion</th> <th> Fusion</th>
</tr> </tr>
</thead> </thead>
</tbody> <tbody>
{% for cworkout in workouts %} {% for cworkout in workouts %}
<tr> <tr>
<td> {{ cworkout.date }} </td> <td> {{ cworkout.date }} </td>
@@ -101,21 +136,10 @@
{% else %} {% else %}
<p> No workouts found </p> <p> No workouts found </p>
{% endif %} {% endif %}
</li>
<div class="grid_2 prefix_5 suffix_1 omega"> </ul>
<span class="button gray small"> {% endblock %}
{% if workouts.has_previous %}
<a class="wh" href="/rowers/workout/fusion/{{ id }}/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}?page={{ workouts.previous_page_number }}">&lt;</a> {% block sidebar %}
{% endif %} {% include 'menu_workout.html' %}
<span>
Page {{ workouts.number }} of {{ workouts.paginator.num_pages }}.
</span>
{% if workouts.has_next %}
<a class="wh" href="/rowers/workout/fusion/{{ id }}/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}?page={{ workouts.next_page_number }}">&gt;</a>
{% endif %}
</span>
</div>
</div>
{% endblock %} {% endblock %}
+23 -24
View File
@@ -1,13 +1,12 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}GDPR Opt-In{% endblock %} {% block title %}GDPR Opt-In{% endblock %}
{% block content %} {% block main %}
<div class="grid_12"> <h2>GDPR Opt-In</h2>
<h2>GDPR Opt-In</h2> <p>
<p>
<b> <b>
To comply with the European Union General Data Protection Regulation, To comply with the European Union General Data Protection Regulation,
we need to record your consent to use personal data on this website. we need to record your consent to use personal data on this website.
@@ -17,37 +16,37 @@
account. This will irreversibly delete all your data on rowsandall.com account. This will irreversibly delete all your data on rowsandall.com
and remove your account. and remove your account.
</b> </b>
</p> </p>
<hr> <hr>
{% include "privacypolicy.html" %} {% include "privacypolicy.html" %}
<hr> <hr>
<p> <p>
To start or continue using the site, please give your consent by clicking on the green Opt In button below. To start or continue using the site, please give your consent by clicking on the green Opt In button below.
</p> </p>
<p> <p>
<div class="grid_2 suffix_10 alpha">
<p>
<a class="button gray small" href="/rowers/exportallworkouts">Download your data</a> <a class="button gray small" href="/rowers/exportallworkouts">Download your data</a>
</p> </p>
</div>
</p>
<div class="grid_2 alpha"> <p>
<a href="/rowers/me/gdpr-optin-confirm/?next={{ next }}" class="button green small">Opt in and continue</a> <a class="button gray small" href="/rowers/me/gdpr-optin-confirm/?next={{ next }}">Opt in and continue</a>
</div> </p>
<p>
<form method="POST" action="/rowers/me/delete" class="padding"> <form method="POST" action="/rowers/me/delete" class="padding">
{% csrf_token %} {% csrf_token %}
<input id="id_delete_user" type="hidden" name="delete_user" value="True"> <input id="id_delete_user" type="hidden" name="delete_user" value="True">
<div class="grid_2 prefix_2">
<input class="button red small" type="submit" name="action" value="DELETE ACCOUNT"> <input class="button red small" type="submit" name="action" value="DELETE ACCOUNT">
</div>
</form> </form>
</p>
</div>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_profile.html' %}
{% endblock %}
+20 -33
View File
@@ -1,43 +1,30 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}Delete Graph Image {% endblock %} {% block title %}Delete Graph Image {% endblock %}
{% block content %} {% block main %}
<div id="workouts" class="grid_6 alpha"> <ul class="main-content">
<li class="grid_2">
{% if form.errors %} <form action="" method="post">
<p style="color: red;"> {% csrf_token %}
Please correct the error{{ form.errors|pluralize }} below. <p>Are you sure you want to delete this chart?</p>
</p>
{% endif %}
<h1>Confirm Graph Delete</h1>
<p>This will permanently delete the graph</p>
<div class="grid_2 alpha">
<p> <p>
<a class="button green small" href="/rowers/list-workouts/">Cancel</a> <input class="button red" type="submit" value="Confirm">
</div>
<div class="grid_2">
<p>
<a class="button red small" href="/rowers/graph/{{ graph.id }}/delete">Delete</a>
</p> </p>
</div> </form>
</li>
</div> <li class="grid_2">
<a href="/rowers/graph/{{ object.id }}">
<div id="images" class="grid_6 omega"> <image src="/{{ object.filename }}" alt="{{ object.filename }}"/>
<p> </a>
<a href="/{{ graph.filename }}" download="myimage"> </li>
<image src="/{{ graph.filename }}" alt="/{{ graph.filename }}" width="480"/> </ul>
</a>
</p>
</div>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_workouts.html' %}
{% endblock %}
+160 -3
View File
@@ -3,11 +3,168 @@
{% load rowerfilters %} {% load rowerfilters %}
{% block main %} {% block main %}
<h1>Main</h1> <h1>Welcome to Rowsandall.com</h1>
<p>Vestibulum consectetur sit amet nisi ut consectetur. Praesent efficitur, nibh vitae fringilla scelerisque, est neque faucibus quam, in iaculis purus libero eget mauris. Curabitur et luctus sapien, ac gravida orci. Aliquam erat volutpat. In hac habitasse platea dictumst. Aenean commodo, arcu a commodo efficitur, libero dolor mollis turpis, non posuere orci leo eget enim. Curabitur sit amet elementum orci, pulvinar dignissim urna. Morbi id ex eu ex congue laoreet. Aenean tincidunt dolor justo, semper pretium libero luctus nec. Ut vulputate metus accumsan leo imperdiet tincidunt. Phasellus nec rutrum dolor. Cras imperdiet sollicitudin arcu, id interdum nibh <a href="">fermentum</a> in. <ul class="main-content">
<li class="grid_2">
<h2>What is it?</h2>
<p>
Rowsandall.com is an online tool for rowers to analyze data from On The Water
(OTW) and On The Erg (OTE) workouts. It accepts workout data from a
number of devices and applications. It analyzes the data to provide
valuable insights about your training, and enables you to share
data with many common online training tracking systems.
</p> </p>
<p>Vestibulum consectetur sit amet nisi ut consectetur. Praesent efficitur, nibh vitae fringilla scelerisque, est neque faucibus quam, in iaculis purus libero eget mauris. Curabitur et luctus sapien, ac gravida orci. Aliquam erat volutpat. In hac habitasse platea dictumst. Aenean commodo, arcu a commodo efficitur, libero dolor mollis turpis, non posuere orci leo eget enim. Curabitur sit amet elementum orci, pulvinar dignissim urna. Morbi id ex eu ex congue laoreet. Aenean tincidunt dolor justo, semper pretium libero luctus nec. Ut vulputate metus accumsan leo imperdiet tincidunt. Phasellus nec rutrum dolor. Cras imperdiet sollicitudin arcu, id interdum nibh <a href="">fermentum</a> in. <h2>Indoor Rowing</h2>
<p>
rowsandall.com is designed to work with all models of the Concept2
Indoor rower. Using applications like ergstick, rowpro, ergdata or
painsled; a user can collect stroke by stroke data from the Concept2
Performance Monitor (Models PM3, PM4 or PM5). Workout data can be exported
from these applications, usually in CSV format, and uploaded to
rowsandall.com. Users can upload workouts either through the online
interface, for by emailing workouts to the site to simplify the
process for some applications.
</p> </p>
<h2>On The Water Rowing</h2>
<p>
On the water rowers use either dedicated devices like Speedcoaches or
smartphone applications to collect data on their workouts. All of these
devices and applications provide a method to export workout data in CSV,
TCX or FIT format files. Workout data in these formats can be uploaded
to rowsandall.com. Users can upload workouts either through the online
interface, for by emailing workouts to the site to simplify the process
for some applications.
</p>
<h2>Basic Analysis</h2>
<p>
Many athletes use training approaches that use heart rate as a key metric. In general, HR training is managed by defining different training zones for different purposes. Rowsandall.com uses heart rate zone definitions that are consistent with the Concept2 Training Guide.
</p>
<p>
After a user defines their training zones, any training files that are uploaded with HR data can be analyzed to provide time in HR zone pie charts.
</p>
<p>
The tools also provide the ability to review a row, stroke by stroke in plots versus time or distance. Basic plots in include HR, Pace, Stroke rate, and power for the erg.
</p>
<p>
The tools also provide a text summary of the row.
</p>
<h2>Workout Export</h2>
<p>
rowsandall.com provides the ability to easily export workouts from the erg or boat to the Concept2 online logbook. Export to other sport tracking sites like Strava and SportTracks is also supported. Users can also export workout data by email.
</p>
<h2>Import Compatibility</h2>
<p>
Rowsandall.com tries to be compatible with the most important tools that rowers use to capture the data (both indoor and OTW). The list of supported tools
continues to be expanded.
</p>
</li>
<li class="grid_2">
<h2>Getting your data on rowsandall.com</h2>
<p>
To start using the tool, you first need to get some workouts in it.
There are basically two ways. The first method works with a workout file
(CSV, FIT, TCX, etc). The details are described in this
<a href="https://analytics.rowsandall.com/2017/11/08/getting-your-data-on-rowsandall-com/">blog post</a>.
A straightforward way to upload your data is to use the
<a href="/rowers/upload">Upload Page</a>.
</p>
<p>
The second way to get data into the tool is by importing them
from other workout tracking portals like Strava, SportTracks, etc.
To do this, you use the Import menu on the left of the
<a href="/rowers/list-workouts">Workouts List</a> page. For this
to work, you need to have coupled the external fitness tracking
site with rowsandall.com. You can do this in your
<a href="/rowers/me/edit">User Profile</a>. Don't worry, the site
will guide you through the process.
</p>
<h2>User settings</h2>
<p>Talking about the <a href="/rowers/me/edit">user profile</a>,
we recommend that you look
at what parameters can be set there. To get the most out of
the site, we recommend you set the heart rate and power zones,
as well as check that your age and gender are correct. Exercise
data make much more sense when this context is taken into account.
</p>
<h2>Exploring a workout</h2>
<p>
In the <a href="/rowers/list-workouts">Workouts List</a>,
you can click on the name of a workout to open it.
Once you're on a workout page, the menu on the left will
give you all possibilities you have to edit, manipulate, chart,
or analyze the workout data.
</p>
<p>
When you are about to do something irreversible (like deleting a workout)
the site will ask for a confirmation, so don't hesitate to explore.
</p>
<h2>Analysis</h2>
<p>
Some of our functionality is not related to a single workout, but instead
looks at comparisons, trends, statistics, and other. You can find all
that under the <a href="/rowers/analysis">Analysis Tab</a>.
</p>
<h2>On-line Racing</h2>
<p>
<a href="/rowers/virtualevents">On-line racing</a> is a
fun way to race other Rowsandall.com users
rowing on the same stretch of water.
</p>
<h2>Training Plan</h2>
<p>
Under the <a href="/rowers/sessions">Plan</a> tab, you
will find your training plan and functionality to see how
you are progressing towards your goals.
</p>
<h2>Teams</h2>
<p>
The <a href="/rowers/team">Teams</a> tab brings you to
functionality related to interaction with your team, if you
are part of one.
</p>
</li>
<li class="grid_4">
<h2>Need more help?</h2>
<p>
The links in the menu on the left bring you to our blog, where we
regularly publish how-to's and articles about new functionality, to
our Facebook group where you can discuss with other users, and to
a contact page where you can learn how to contact the developers
of this site.
</p>
</ul>
{% endblock %}
{% block sideheader %}
<h1>Help</h1>
{% endblock %} {% endblock %}
{% block sidebar %} {% block sidebar %}
+87 -101
View File
@@ -1,16 +1,16 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}Rowsandall Histogram {% endblock %} {% block title %}Rowsandall {% endblock %}
{% block content %} {% block main %}
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script> <script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
<script> <script>
$(function() { $(function() {
// Get the form fields and hidden div // Get the form fields and hidden div
var checkbox = $("#id_water"); var modality = $("#id_modality");
var hidden = $("#id_waterboattype"); var hidden = $("#id_waterboattype");
@@ -20,14 +20,19 @@
hidden.hide(); hidden.hide();
if (modality.val() == 'water') {
hidden.show();
}
// Setup an event listener for when the state of the // Setup an event listener for when the state of the
// checkbox changes. // checkbox changes.
checkbox.change(function() { modality.change(function() {
// Check to see if the checkbox is checked. // Check to see if the checkbox is checked.
// If it is, show the fields and populate the input. // If it is, show the fields and populate the input.
// If not, hide the fields. // If not, hide the fields.
if (checkbox.is(':checked')) { var Value = modality.val();
if (Value=='water') {
// Show the hidden fields. // Show the hidden fields.
hidden.show(); hidden.show();
} else { } else {
@@ -45,117 +50,98 @@
// $("#hidden_field").val(""); // $("#hidden_field").val("");
} }
}); });
});
});
</script> </script>
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
<script async="true" type="text/javascript">
Bokeh.set_log_level("info");
</script>
{{ interactiveplot |safe }} <div id="id_css_res">
<link rel="stylesheet" href="/static/css/bokeh-0.12.3.min.css" type="text/css" />
<link rel="stylesheet" href="/static/css/bokeh-widgets-0.12.3.min.css" type="text/css" />
</div>
<div id="id_js_res">
<script
type="text/javascript" src="/static/js/bokeh-0.12.3.min.js">
</script>
<script
type="text/javascript" src="/static/js/bokeh-widgets-0.12.3.min.js">
</script>
<script> </div>
// Set things up to resize the plot on a window resize. You can play with
// the arguments of resize_width_height() to change the plot's behavior. <script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
var plot_resize_setup = function () {
var plotid = Object.keys(Bokeh.index)[0]; // assume we have just one plot
var plot = Bokeh.index[plotid];
var plotresizer = function() {
// arguments: use width, use height, maintain aspect ratio
plot.resize_width_height(true, false, false);
};
window.addEventListener('resize', plotresizer);
plotresizer();
};
window.addEventListener('load', plot_resize_setup);
</script>
<style>
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
html, body {height: 100%; margin:5px;}
</style>
<div id="title" class="grid_12 alpha"> <div id="id_script">
<div class="grid_10 alpha">
{% if theuser %} </div>
<h3>{{ theuser.first_name }}'s Stroke Analysis</h3>
{% else %} <ul class="main-content">
<h3>{{ user.first_name }}'s Stroke Analysis</h3>
{% endif %} <li class="grid_4">
<p>Summary for {{ theuser.first_name }} {{ theuser.last_name }}
between {{ startdate|date }} and {{ enddate|date }}</p>
</li>
<li class="grid_4">
<div id="id_chart">
{{ the_div|safe }}
</div> </div>
<div class="grid_2 omega"> </li>
{% if user.is_authenticated and user|is_manager %} <li>
<div class="grid_2 alpha dropdown">
<button class="grid_2 alpha button green small dropbtn">
{{ theuser.first_name }} {{ theuser.last_name }}
</button>
<div class="dropdown-content">
{% for member in user|team_members %}
<a class="button green small" href="/rowers/{{ member.id }}/flexall/{{ xparam }}/{{ yparam1 }}/{{ yparam2 }}/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}">{{ member.first_name }} {{ member.last_name }}</a>
{% endfor %}
</div>
{% else %}
&nbsp;
</div>
{% endif %}
</div>
</div>
<div class="grid_12 alpha">
<div id="form" class="grid_6 alpha">
<p>Warning: Large date ranges may take a long time to load. Huge date ranges may crash your browser.</p>
<form enctype="multipart/form-data" action="{{ formloc }}" method="post"> <form enctype="multipart/form-data" action="{{ formloc }}" method="post">
{% csrf_token %}
<div class="grid_2 alpha">
<table> <table>
{{ optionsform.as_table }} {{ optionsform.as_table }}
</table> </table>
</div>
<div class="grid_2 suffix_2 omega">
<input type="hidden" name="options" value="options"> <input type="hidden" name="options" value="options">
<input class="grid_1 alpha button green small" value="Submit" type="Submit"> </li>
</div> <li>
</form>
</div>
<div class="grid_6 omega">
<p>Use this form to select a different date range:</p>
<p>
Select start and end date for a date range:
<div class="grid_4 alpha">
<form enctype="multipart/form-data" action="" method="post">
<table> <table>
{{ form.as_table }} {{ form.as_table }}
</table> </table>
</li>
<li>
{% csrf_token %} {% csrf_token %}
</div> <input class="button green small" value="Submit" type="Submit">
<div class="grid_2 omega">
<input name='daterange' class="button green" type="submit" value="Submit"> </form>
</div>
<div class="grid_4 alpha">
<form enctype="multipart/form-data" action="" method="post">
Or use the last {{ deltaform }} days.
</div>
<div class="grid_2 omega">
{% csrf_token %}
<input name='datedelta' class="button green" type="submit" value="Submit">
</form> </form>
</div> </li>
</div> </ul>
</div>
<div id="summary" class="grid_6 suffix_6 alpha">
<p>Summary for {{ theuser.first_name }} {{ theuser.last_name }}
between {{ startdate|date }} and {{ enddate|date }}</p>
</div>
</div>
<div id="graph" class="grid_12 alpha">
{{ the_div|safe }}
</div>
{% endblock %} {% endblock %}
{% block scripts %}
<script type='text/javascript'
src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js'>
</script>
<script>
$(function($) {
console.log('loading script');
$.getJSON(window.location.protocol + '//'+window.location.host + '/rowers/histodata', function(json) {
console.log('got script');
var counter=0;
var script = json.script;
var div = json.div;
console.log('set vars');
$("#id_sitready").remove();
console.log('sitready removed');
$("#id_chart").append(div);
console.log('div appended');
$("#id_script").append("<script>"+script+"</s"+"cript>");
console.log('script changed');
});
});
</script>
{% endblock %}
{% block sidebar %}
{% include 'menu_analytics.html' %}
{% endblock %}
+18 -50
View File
@@ -1,66 +1,34 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}View Workout {% endblock %} {% block title %}View Workout {% endblock %}
{% block content %} {% block main %}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>
{{ interactiveplot |safe }} {{ interactiveplot |safe }}
<script>
// Set things up to resize the plot on a window resize. You can play with
// the arguments of resize_width_height() to change the plot's behavior.
var plot_resize_setup = function () {
var plotid = Object.keys(Bokeh.index)[0]; // assume we have just one plot
var plot = Bokeh.index[plotid];
var plotresizer = function() {
// arguments: use width, use height, maintain aspect ratio
plot.resize_width_height(true, false, false);
};
window.addEventListener('resize', plotresizer);
plotresizer();
};
window.addEventListener('load', plot_resize_setup);
</script>
<style>
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
html, body {height: 100%; margin:5px;}
</style>
<div id="navigation" class="grid_12 alpha">
{% if user.is_authenticated and mayedit %}
<div class="grid_2 alpha">
<p>
<a class="button gray small" href="/rowers/workout/{{ id }}/edit">Edit Workout</a>
</p>
</div>
<div class="grid_2 suffix_8 omega">
<p>
<a class="button gray small" href="/rowers/workout/{{ id }}/advanced">Advanced Edit</a>
</p>
</div>
{% endif %}
</div>
<div id="title" class="grid_12 alpha"> {% if user.is_authenticated and mayedit %}
<h1>Indoor Rower Power Histogram</h1> <h1>Indoor Rower Power Histogram</h1>
</div> <ul class="main-content">
<li class="grid_4">
<div id="graph" class="grid_12 alpha">
{{ the_div|safe }} {{ the_div|safe }}
</div> </li>
</ul>
{% endif %}
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_workout.html' %}
{% endblock %}
+17 -16
View File
@@ -1,4 +1,4 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
@@ -15,14 +15,16 @@
</script> </script>
{% endblock %} {% endblock %}
{% block content %} {% block main %}
<div id="id_dropregion" class="grid_12 alpha watermark invisible"> <h1>Upload Image</h1>
<ul class="main-content">
<li class="grid_4">
<div id="id_dropregion" class="watermark invisible">
<p>Drag and drop files here </p> <p>Drag and drop files here </p>
</div> </div>
<div id="id_drop-files" class="grid_12 alpha drop-files"> <div id="id_drop-files" class="drop-files">
<form id="file_form" enctype="multipart/form-data" action="{{ formloc }}" method="post"> <form id="file_form" enctype="multipart/form-data" action="{{ formloc }}" method="post">
<div id="left" class="grid_6 alpha">
<h1>Upload Image</h1>
{% if form.errors %} {% if form.errors %}
<p style="color: red;"> <p style="color: red;">
Please correct the error{{ form.errors|pluralize }} below. Please correct the error{{ form.errors|pluralize }} below.
@@ -33,18 +35,13 @@
{{ form.as_table }} {{ form.as_table }}
</table> </table>
{% csrf_token %} {% csrf_token %}
<div id="formbutton" class="grid_1 prefix_4 suffix_1"> <p>
<input class="button green" type="submit" value="Submit"> <input class="button green" type="submit" value="Submit">
</div> </p>
</div>
<div id="right" class="grid_6 omega">
&nbsp;
</div>
</form> </form>
</div> </div>
</li>
</ul>
{% endblock %} {% endblock %}
{% block scripts %} {% block scripts %}
@@ -169,7 +166,7 @@
}); });
$("#id_drop-files").replaceWith( $("#id_drop-files").replaceWith(
'<div id="id_waiting"><img src="/static/img/rowingtimer.gif" width="120" height="100">' '<div id="id_waiting"><img src="/static/img/rowingtimer.gif" width="120" height="100" style="width:120px">'
); );
$.ajax({ $.ajax({
data: data, data: data,
@@ -250,3 +247,7 @@
</script> </script>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_workout.html' %}
{% endblock %}
+24 -44
View File
@@ -1,41 +1,23 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}Advanced Features {% endblock %} {% block title %}Advanced Features {% endblock %}
{% block content %} {% block main %}
<div id="workouts" class="grid_6 alpha"> <h1>In Stroke Metrics</h1>
<ul class="main-content">
{% if form.errors %} <li class="grid_4">
<p style="color: red;">
Please correct the error{{ form.errors|pluralize }} below.
</p>
{% endif %}
<h1>In Stroke Metrics</h1>
{% if user.rower.rowerplan == 'basic' %} {% if user.rower.rowerplan == 'basic' %}
<p>This is a preview of the page with advanced functionality for Pro users. See <a href="/rowers/about">the About page</a> for more information and to sign up for Pro Membership</a>
<p>
This is a preview of the page with advanced functionality for Pro users.
See <a href="/rowers/about">the About page</a> for more information
and to sign up for Pro Membership
</p>
{% endif %} {% endif %}
<div class="grid_2 alpha"> </li>
<p> <li class="grid_2">
<a class="button gray small" href="/rowers/workout/{{ workout.id }}/edit">Edit Workout</a>
</p>
</div>
<div class="grid_2">
<p>
<a class="button gray small" href="/rowers/workout/{{ workout.id }}/advanced">Advanced Edit</a>
</p>
</div>
<div class="grid_2 omega">
<p>
<a class="button gray small" href="/rowers/workout/{{ workout.id }}/export">Export</a>
</p>
</div>
<div class="grid_6 alpha">
<table width=100%> <table width=100%>
<tr> <tr>
<th>Date:</th><td>{{ workout.date }}</td> <th>Date:</th><td>{{ workout.date }}</td>
@@ -50,31 +32,29 @@
<td> <td>
<a href="/rowers/workout/{{ workout.id }}">https://rowsandall.com/rowers/workout/{{ workout.id }}</a> <a href="/rowers/workout/{{ workout.id }}">https://rowsandall.com/rowers/workout/{{ workout.id }}</a>
<td> <td>
</table> </table>
</div> </li>
<div class="grid_6 alpha"> <li>
{% if instrokemetrics %} {% if instrokemetrics %}
{% for metric in instrokemetrics %} {% for metric in instrokemetrics %}
{% if forloop.first %} <p>
<div class="grid_2 alpha">
{% else %}
<div class="grid_2">
{% endif %}
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/instroke/{{ metric }}">{{ metric }}</a> <a class="button blue small" href="/rowers/workout/{{ workout.id }}/instroke/{{ metric }}">{{ metric }}</a>
</div> </p>
{% endfor %} {% endfor %}
{% else %} {% else %}
<p>Unfortunately, this workout doesn't have any in stroke metrics</p> <p>Unfortunately, this workout doesn't have any in stroke metrics</p>
{% endif %} {% endif %}
</div> </li>
</div> </ul>
<div id="advancedplots" class="grid_6 omega">
<p>&nbsp;</p>
</div>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_workout.html' %}
{% endblock %}
+31 -29
View File
@@ -1,22 +1,21 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% block title %}About us{% endblock title %} {% block title %}Legal{% endblock title %}
{% block content %} {% block main %}
<div class="grid_6 alpha"> <h1>Terms and Conditions</h1>
<h2>Terms and Conditions</h2> <h2>Credit</h2>
<h3>Credit</h3>
<p>This document was created using a Contractology template available at <p>This document was created using a Contractology template available at
<a href="http://www.freenetlaw.com">http://www.freenetlaw.com.</a>.</p> <a href="http://www.freenetlaw.com">http://www.freenetlaw.com.</a>.</p>
<h3>Introduction</h3> <h2>Introduction</h2>
<p>These terms and conditions govern your use of this website; by using this website, you accept these terms and conditions in full. If you disagree with these terms and conditions or any part of these terms and conditions, you must not use this website. </p> <p>These terms and conditions govern your use of this website; by using this website, you accept these terms and conditions in full. If you disagree with these terms and conditions or any part of these terms and conditions, you must not use this website. </p>
<p>This website uses cookies. By using this website and agreeing to these terms and conditions, you consent to our rowsandall.com&rsquo;s use of cookies in accordance with the terms of rowsandall.com&rsquo;s privacy policy.</p> <p>This website uses cookies. By using this website and agreeing to these terms and conditions, you consent to our rowsandall.com&rsquo;s use of cookies in accordance with the terms of rowsandall.com&rsquo;s privacy policy.</p>
<h3>License to use website</h3> <h2>License to use website</h2>
<p>Unless otherwise stated, rowsandall.com and/or its licensors own the intellectual property rights in the website and material on the website. Subject to the license below, all these intellectual property rights are reserved.</p> <p>Unless otherwise stated, rowsandall.com and/or its licensors own the intellectual property rights in the website and material on the website. Subject to the license below, all these intellectual property rights are reserved.</p>
@@ -33,7 +32,7 @@
</p> </p>
<h3>Acceptable use</h3> <h2>Acceptable use</h2>
<p>You must not use this website in any way that causes, or may cause, damage to the website or impairment of the availability or accessibility of the website; or in any way which is unlawful, illegal, fraudulent or harmful, or in connection with any unlawful, illegal, fraudulent or harmful purpose or activity.</p> <p>You must not use this website in any way that causes, or may cause, damage to the website or impairment of the availability or accessibility of the website; or in any way which is unlawful, illegal, fraudulent or harmful, or in connection with any unlawful, illegal, fraudulent or harmful purpose or activity.</p>
@@ -44,7 +43,7 @@
<p>You must not use this website to transmit or send unsolicited commercial communications.</p> <p>You must not use this website to transmit or send unsolicited commercial communications.</p>
<h3>Restricted access</h3> <h2>Restricted access</h2>
<p>Access to certain areas of this website is restricted. rowsandall.com reserves the right to restrict access to areas of this website, or indeed this entire website, at rowsandall.com&rsquo;s discretion.</p> <p>Access to certain areas of this website is restricted. rowsandall.com reserves the right to restrict access to areas of this website, or indeed this entire website, at rowsandall.com&rsquo;s discretion.</p>
@@ -52,7 +51,7 @@
<p>rowsandall.com may disable your user ID and password in rowsandall.com&rsquo;s sole discretion without notice or explanation.</p> <p>rowsandall.com may disable your user ID and password in rowsandall.com&rsquo;s sole discretion without notice or explanation.</p>
<h3>User content</h3> <h2>User content</h2>
<p>In these terms and conditions, <q>your user content</q> means material (including without limitation text, images, audio material, video material and audio-visual material) that you submit to this website, for whatever purpose.</p> <p>In these terms and conditions, <q>your user content</q> means material (including without limitation text, images, audio material, video material and audio-visual material) that you submit to this website, for whatever purpose.</p>
@@ -66,7 +65,7 @@
<p>Notwithstanding rowsandall.com&rsquo;s rights under these terms and conditions in relation to user content, rowsandall.com does not undertake to monitor the submission of such content to, or the publication of such content on, this website.</p> <p>Notwithstanding rowsandall.com&rsquo;s rights under these terms and conditions in relation to user content, rowsandall.com does not undertake to monitor the submission of such content to, or the publication of such content on, this website.</p>
<h3>No warranties</h3> <h2>No warranties</h2>
<p>This website is provided <q>as is</q> without any representations or warranties, express or implied. rowsandall.com makes no representations or warranties in relation to this website or the information and materials provided on this website. </p> <p>This website is provided <q>as is</q> without any representations or warranties, express or implied. rowsandall.com makes no representations or warranties in relation to this website or the information and materials provided on this website. </p>
@@ -79,7 +78,7 @@
<p>Nothing on this website constitutes, or is meant to constitute, advice of any kind. If you require advice in relation to any legal, financial or medica] matter you should consult an appropriate professional.</p> <p>Nothing on this website constitutes, or is meant to constitute, advice of any kind. If you require advice in relation to any legal, financial or medica] matter you should consult an appropriate professional.</p>
<h3>Limitations of liability</h3> <h2>Limitations of liability</h2>
<p>rowsandall.com will not be liable to you (whether under the law of contact, the law of torts or otherwise) in relation to the contents of, or use of, or otherwise in connection with, this website: <p>rowsandall.com will not be liable to you (whether under the law of contact, the law of torts or otherwise) in relation to the contents of, or use of, or otherwise in connection with, this website:
@@ -90,7 +89,7 @@
<p>These limitations of liability apply even if rowsandall.com has been expressly advised of the potential loss.</p> <p>These limitations of liability apply even if rowsandall.com has been expressly advised of the potential loss.</p>
<h3>Exceptions</h3> <h2>Exceptions</h2>
<p>Nothing in this website disclaimer will exclude or limit any warranty implied by law that it would be unlawful to exclude or limit; and nothing in this website disclaimer will exclude or limit rowsandall.com&rsquo;s liability in respect of any: <p>Nothing in this website disclaimer will exclude or limit any warranty implied by law that it would be unlawful to exclude or limit; and nothing in this website disclaimer will exclude or limit rowsandall.com&rsquo;s liability in respect of any:
@@ -100,61 +99,59 @@
<li>matter which it would be illegal or unlawful for rowsandall.com to exclude or limit, or to attempt or purport to exclude or limit, its liability. <li>matter which it would be illegal or unlawful for rowsandall.com to exclude or limit, or to attempt or purport to exclude or limit, its liability.
</ul></p> </ul></p>
<h3>Reasonableness</h3> <h2>Reasonableness</h2>
<p>By using this website, you agree that the exclusions and limitations of liability set out in this website disclaimer are reasonable. </p> <p>By using this website, you agree that the exclusions and limitations of liability set out in this website disclaimer are reasonable. </p>
<p>If you do not think they are reasonable, you must not use this website.</p> <p>If you do not think they are reasonable, you must not use this website.</p>
<h3>Other parties</h3> <h2>Other parties</h2>
<p>You agree that the limitations of warranties and liability set out in this website disclaimer will protect rowsandall.com&rsquo;s officers, employees, agents, subsidiaries, successors, assigns and sub-contractors as well as rowsandall.com. </p> <p>You agree that the limitations of warranties and liability set out in this website disclaimer will protect rowsandall.com&rsquo;s officers, employees, agents, subsidiaries, successors, assigns and sub-contractors as well as rowsandall.com. </p>
<h3>Unenforceable provisions</h3> <h2>Unenforceable provisions</h2>
<p>If any provision of this website disclaimer is, or is found to be, unenforceable under applicable law, that will not affect the enforceability of the other provisions of this website disclaimer.</p> <p>If any provision of this website disclaimer is, or is found to be, unenforceable under applicable law, that will not affect the enforceability of the other provisions of this website disclaimer.</p>
<h3>Indemnity</h3> <h2>Indemnity</h2>
<p>You hereby indemnify rowsandall.com and undertake to keep rowsandall.com indemnified against any losses, damages, costs, liabilities and expenses (including without limitation legal expenses and any amounts paid by rowsandall.com to a third party in settlement of a claim or dispute on the advice of rowsandall.com&rsquo;s legal advisers) incurred or suffered by rowsandall.com arising out of any breach by you of any provision of these terms and conditions, or arising out of any claim that you have breached any provision of these terms and conditions.</p> <p>You hereby indemnify rowsandall.com and undertake to keep rowsandall.com indemnified against any losses, damages, costs, liabilities and expenses (including without limitation legal expenses and any amounts paid by rowsandall.com to a third party in settlement of a claim or dispute on the advice of rowsandall.com&rsquo;s legal advisers) incurred or suffered by rowsandall.com arising out of any breach by you of any provision of these terms and conditions, or arising out of any claim that you have breached any provision of these terms and conditions.</p>
<h3>Breaches of these terms and conditions</h3> <h2>Breaches of these terms and conditions</h2>
<p>Without prejudice to rowsandall.com&rsquo;s other rights under these terms and conditions, if you breach these terms and conditions in any way, rowsandall.com may take such action as rowsandall.com deems appropriate to deal with the breach, including suspending your access to the website, prohibiting you from accessing the website, blocking computers using your IP address from accessing the website, contacting your internet service provider to request that they block your access to the website and/or bringing court proceedings against you.</p> <p>Without prejudice to rowsandall.com&rsquo;s other rights under these terms and conditions, if you breach these terms and conditions in any way, rowsandall.com may take such action as rowsandall.com deems appropriate to deal with the breach, including suspending your access to the website, prohibiting you from accessing the website, blocking computers using your IP address from accessing the website, contacting your internet service provider to request that they block your access to the website and/or bringing court proceedings against you.</p>
<h3>Variation</h3> <h2>Variation</h2>
<p>rowsandall.com may revise these terms and conditions from time-to-time. Revised terms and conditions will apply to the use of this website from the date of the publication of the revised terms and conditions on this website. Please check this page regularly to ensure you are familiar with the current version.</p> <p>rowsandall.com may revise these terms and conditions from time-to-time. Revised terms and conditions will apply to the use of this website from the date of the publication of the revised terms and conditions on this website. Please check this page regularly to ensure you are familiar with the current version.</p>
<h3>Assignment</h3> <h2>Assignment</h2>
<p>rowsandall.com may transfer, sub-contract or otherwise deal with rowsandall.com&rsquo;s rights and/or obligations under these terms and conditions without notifying you or obtaining your consent.</p> <p>rowsandall.com may transfer, sub-contract or otherwise deal with rowsandall.com&rsquo;s rights and/or obligations under these terms and conditions without notifying you or obtaining your consent.</p>
<p>You may not transfer, sub-contract or otherwise deal with your rights and/or obligations under these terms and conditions. </p> <p>You may not transfer, sub-contract or otherwise deal with your rights and/or obligations under these terms and conditions. </p>
<h3>Severability</h3> <h2>Severability</h2>
<p>If a provision of these terms and conditions is determined by any court or other competent authority to be unlawful and/or unenforceable, the other provisions will continue in effect. If any unlawful and/or unenforceable provision would be lawful or enforceable if part of it were deleted, that part will be deemed to be deleted, and the rest of the provision will continue in effect. </p> <p>If a provision of these terms and conditions is determined by any court or other competent authority to be unlawful and/or unenforceable, the other provisions will continue in effect. If any unlawful and/or unenforceable provision would be lawful or enforceable if part of it were deleted, that part will be deemed to be deleted, and the rest of the provision will continue in effect. </p>
<h3>Entire agreement</h3> <h2>Entire agreement</h2>
<p>These terms and conditions constitute the entire agreement between you and rowsandall.com in relation to your use of this website, and supersede all previous agreements in respect of your use of this website.</p> <p>These terms and conditions constitute the entire agreement between you and rowsandall.com in relation to your use of this website, and supersede all previous agreements in respect of your use of this website.</p>
<h3>Law and jurisdiction</h3> <h2>Law and jurisdiction</h2>
<p>These terms and conditions will be governed by and construed in accordance with Czech Law and any disputes relating to these terms and conditions will be subject to the exclusive jurisdiction of the courts of The Czech Republic.</p> <p>These terms and conditions will be governed by and construed in accordance with Czech Law and any disputes relating to these terms and conditions will be subject to the exclusive jurisdiction of the courts of The Czech Republic.</p>
<h3>rowsandall.com&rsquo;s details</h3> <h2>rowsandall.com&rsquo;s details</h2>
<p>The rowsandall.com site is owned by Rowsandall s.r.o., Nov&eacute; sady 988/2, Star&eacute; Brno, 602 00 Brno, Czech Republic (company identification number 070 48 572)</p> <p>The rowsandall.com site is owned by Rowsandall s.r.o., Nov&eacute; sady 988/2, Star&eacute; Brno, 602 00 Brno, Czech Republic (company identification number 070 48 572)</p>
<p>You can contact rowsandall.com by using the <a href="/rowers/email/">email contact form.</a></p> <p>You can contact rowsandall.com by using the <a href="/rowers/email/">email contact form.</a></p>
</div>
<div class="grid_6 omega">
<h2>Privacy Policy</h2> <h2>Privacy Policy</h2>
{% include "privacypolicy.html" %} {% include "privacypolicy.html" %}
@@ -162,5 +159,10 @@
</div>
{% endblock content %} {% endblock main %}
{% block sidebar %}
{% include 'menu_help.html' %}
{% endblock %}
+24 -34
View File
@@ -1,4 +1,4 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
@@ -8,7 +8,7 @@
{% endblock %} {% endblock %}
{% block content %} {% block main %}
<style> <style>
#mypointer { #mypointer {
cursor: pointer; cursor: pointer;
@@ -17,12 +17,12 @@
<div class="grid_12"> <h1>Courses</h1>
<div id="courses_table" class="grid_8 alpha">
<h1>Courses</h1>
<ul class="main-content">
<li class="grid_3">
{% if courses %} {% if courses %}
<p>
<table width="100%" class="listtable shortpadded"> <table width="100%" class="listtable shortpadded">
<thead> <thead>
<tr> <tr>
@@ -51,38 +51,24 @@
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
</p>
{% else %} {% else %}
<p> No courses found </p> <p> No courses found </p>
{% endif %} {% endif %}
</li>
<div class="grid_6 alpha"> <li>
<div class="grid_2 prefix_1 alpha"> <p>
<a class="button small green" href="/rowers/courses/upload">Add Courses</a>
</div>
<p>&nbsp;</p>
<form id="searchform" action="/rowers/list-courses/" <form id="searchform" action="/rowers/list-courses/"
method="get" accept-charset="utf-8"> method="get" accept-charset="utf-8">
<div class="grid_3 prefix_1 alpha">
<input class="searchfield" id="searchbox" name="q" type="text" placeholder="Search"> <input class="searchfield" id="searchbox" name="q" type="text" placeholder="Search">
</div>
<div class="grid_1 omega">
<button class="button blue small" type="submit"> <button class="button blue small" type="submit">
Search Search
</button> </button>
</div>
</form> </form>
</div> </p>
<div class="grid_2 omega"> <p>
&nbsp; <a class="button small green" href="/rowers/courses/upload">Add Courses</a>
</div> </p>
</div>
<div class="grid_4 omega">
<div class="grid_4" id="announcements">
{% if announcements %} {% if announcements %}
<h3>What's New?</h3> <h3>What's New?</h3>
{% for a in announcements %} {% for a in announcements %}
@@ -95,8 +81,10 @@
{% endfor %} {% endfor %}
<p>&nbsp;</p> <p>&nbsp;</p>
{% endif %} {% endif %}
</div>
<div class="grid_4" id="about"> </li>
<li class="grid_4">
<h2>How-to</h2> <h2>How-to</h2>
<p> <p>
Courses allow you to mark the start & finish lines of your Courses allow you to mark the start & finish lines of your
@@ -142,9 +130,11 @@
Your CrewNerd "courses.kml" file works out of the box</p> Your CrewNerd "courses.kml" file works out of the box</p>
<p>The site doesn't test for duplicate courses.</p> <p>The site doesn't test for duplicate courses.</p>
</div>
</div>
</li>
</div> </ul>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_racing.html' %}
{% endblock %}
+71 -44
View File
@@ -1,4 +1,4 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
@@ -8,61 +8,88 @@
{% include "monitorjobs.html" %} {% include "monitorjobs.html" %}
{% endblock %} {% endblock %}
{% block content %} {% block main %}
<h1>Recent Graphs</h1> <h1>Recent Graphs</h1>
<form id="searchform" action="." <ul class="main-content">
{% if graphs %}
<li class="grid_2">
<form id="searchform" action="."
method="get" accept-charset="utf-8"> method="get" accept-charset="utf-8">
<button class="button blue small" type="submit"> <button class="button blue small" type="submit">
Search Search
</button> </button>
<input class="searchfield" id="searchbox" name="q" type="text" placeholder="Search"> <input class="searchfield" id="searchbox" name="q" type="text" placeholder="Search">
</form> </form>
{% if graphs1 %} </li>
<div class="grid_1 alpha"> <li class="grid_2">
<p>&nbsp;</p> <p>
</div> <span>
{% if graphs.has_previous %}
{% if request.GET.q %}
<a class="wh" href="?page=1&q={{ request.GET.q }}">
<i class="fas fa-arrow-alt-to-left"></i>
</a>
<a class="wh" href="?page={{ workouts.previous_page_number }}&q={{ request.GET.q }}">
<i class="fas fa-arrow-alt-left"></i>
</a>
{% else %}
<a class="wh" href="?page=1">
<i class="fas fa-arrow-alt-to-left"></i>
</a>
<a class="wh" href="?page={{ graphs.previous_page_number }}">
<i class="fas fa-arrow-alt-left"></i>
</a>
{% endif %}
{% endif %}
{% for graph in graphs1 %} <span>
<div id="thumb-container" class="grid_2"> Page {{ graphs.number }} of {{ graphs.paginator.num_pages }}.
<p class="caption"><a href="/rowers/graph/{{ graph.id }}/"> </span>
{% if graphs.has_next %}
{% if request.GET.q %}
<a class="wh" href="?page={{ graphs.next_page_number }}&q={{ request.GET.q }}">
<i class="fas fa-arrow-alt-right"></i>
</a>
<a class="wh" href="?page={{ graphs.paginator.num_pages }}&q={{ request.GET.q }}">
<i class="fas fa-arrow-alt-to-right">
</a>
{% else %}
<a class="wh" href="?page={{ graphs.next_page_number }}">
<i class="fas fa-arrow-alt-right"></i>
</a>
<a class="wh" href="?page={{ graphs.paginator.num_pages }}">
<i class="fas fa-arrow-alt-to-right"></i>
</a>
{% endif %}
{% endif %}
</span>
</p>
</li>
{% for graph in graphs %}
<li>
<p class="caption">
<a href="/rowers/graph/{{ graph.id }}/">
<img src="/{{ graph.filename }}" <img src="/{{ graph.filename }}"
onerror="this.src='/static/img/rowingtimer.gif'" onerror="this.src='/static/img/rowingtimer.gif'"
alt="{{ graph.filename }}" width="120" height="100"></a></p> alt="{{ graph.filename }}" width="120" height="100">
</a>
</p>
<p class="caption">{{ graph.workout.name }}</p> <p class="caption">{{ graph.workout.name }}</p>
</div> </li>
{% endfor %} {% endfor %}
<div class="grid_1 omega">
<p>&nbsp;</p>
</div>
<div class="grid_12">
<p>&nbsp;</p>
</div>
<div class="grid_1 alpha">
<p>&nbsp;</p>
</div>
{% for graph in graphs2 %}
<div id="thumb-container" class="grid_2">
<a href="/rowers/graph/{{ graph.id }}/">
<p class="caption"><img src="/{{ graph.filename }}"
onerror="this.src='/static/img/rowingtimer.gif'"
alt="{{ graph.filename }}" width="120" height="100"></a></p>
<p class="caption">{{ graph.workout.name }}</p>
</div>
{% endfor %}
<div class="grid_1 omega">
<p>&nbsp;</p>
</div>
{% else %} {% else %}
<p> No graphs found </p> <li class="grid_4">
<p>
No charts found
</p>
</li>
{% endif %} {% endif %}
</ul>
{% endblock %}
{% block sidebar %}
{% include 'menu_workouts.html' %}
{% endblock %} {% endblock %}
+106 -173
View File
@@ -1,7 +1,7 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
xo
{% block title %}Rowsandall Workouts List{% endblock %} {% block title %}Rowsandall Workouts List{% endblock %}
{% block scripts %} {% block scripts %}
@@ -41,64 +41,116 @@
{% endblock %} {% endblock %}
{% block content %} {% block main %}
<style> <style>
#mypointer { #mypointer {
cursor: pointer; cursor: pointer;
} }
</style> </style>
<div class="grid_12"> <ul class="main-content">
<li class="grid_2">
<div class="grid_4 alpha"> <p>
{% if team %}
<form enctype="multipart/form-data" method="post"> <form enctype="multipart/form-data" method="post">
{% else %}
<form enctype="multipart/form-data" method="post">
{% endif %}
<table> <table>
{{ dateform.as_table }} {{ dateform.as_table }}
</table> </table>
{% csrf_token %} {% csrf_token %}
</div> <input name='daterange' type="submit" value="Submit">
<div class="grid_2 alpha"> </form>
<input name='daterange' class="button green" type="submit" value="Submit"> </form> </p>
</div> {% if team %}
{% if user.is_authenticated and user|is_manager %} <p>
<div class="grid_2 dropdown"> <form id="searchform" action="/rowers/list-workouts/team/{{ team.id }}/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}"
<button class="grid_2 alpha button green small dropbtn"> method="get" accept-charset="utf-8">
{{ rower.user.first_name }} {{ rower.user.last_name }}
</button>
<div class="dropdown-content">
{% for member in user|team_members %}
<a class="button green small" href="/rowers/u/{{ member.id }}/list-workouts/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}">{{ member.first_name }} {{ member.last_name }}</a>
{% endfor %}
</div>
</div>
{% else %} {% else %}
&nbsp; <form id="searchform" action="/rowers/list-workouts/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}"
method="get" accept-charset="utf-8">
{% endif %} {% endif %}
<input class="searchfield" id="searchbox" name="q" type="text" placeholder="Search">
<input type="submit">
</input>
</form>
</p>
</li>
<li class="grid_2">
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
<script async="true" type="text/javascript">
Bokeh.set_log_level("info");
</script>
{{ interactiveplot |safe }}
</div> {{ the_div |safe }}
</li>
{% if team %} <li>
<div class="grid_12 alpha">
{% include "teambuttons.html" with teamid=team.id team=team %}
</div>
{% endif %}
<div class="grid_12">
<div id="workouts_table" class="grid_8 alpha">
{% if team %} {% if team %}
<h3>{{ team.name }} Team Workouts</h3> <h3>{{ team.name }} Team Workouts</h3>
{% else %} {% else %}
<h3>Workouts of {{ rower.user.first_name }} {{ rower.user.last_name }}</h3> <h3>
Workouts of {{ rower.user.first_name }} {{ rower.user.last_name }}
</h3>
{% endif %} {% endif %}
</li>
<li>
<p>
<span>
{% if workouts.has_previous %}
{% if request.GET.q %}
<a class="wh" href="?page=1&q={{ request.GET.q }}">
<i class="fas fa-arrow-alt-to-left"></i>
</a>
<a class="wh" href="?page={{ workouts.previous_page_number }}&q={{ request.GET.q }}">
<i class="fas fa-arrow-alt-left"></i>
</a>
{% else %}
<a class="wh" href="?page=1">
<i class="fas fa-arrow-alt-to-left"></i>
</a>
<a class="wh" href="?page={{ workouts.previous_page_number }}">
<i class="fas fa-arrow-alt-left"></i>
</a>
{% endif %}
{% endif %}
<span>
Page {{ workouts.number }} of {{ workouts.paginator.num_pages }}.
</span>
{% if workouts.has_next %}
{% if request.GET.q %}
<a class="wh" href="/rowers/list-workouts/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}?page={{ workouts.next_page_number }}&q={{ request.GET.q }}">
<i class="fas fa-arrow-alt-right"></i>
</a>
<a class="wh" href="?page={{ workouts.paginator.num_pages }}&q={{ request.GET.q }}">
<i class="fas fa-arrow-alt-to-right">
</a>
{% else %}
<a class="wh" href="/rowers/list-workouts/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}?page={{ workouts.next_page_number }}">
<i class="fas fa-arrow-alt-right"></i>
</a>
<a class="wh" href="?page={{ workouts.paginator.num_pages }}">
<i class="fas fa-arrow-alt-to-right"></i>
</a>
{% endif %}
{% endif %}
</span>
</p>
</li>
<li>
<p>
{% if rankingonly and not team %}
<a href="/rowers/list-workouts">
<i class="far fa-star"></i>Show All Workouts
</a>
{% elif not team %}
<a href="/rowers/list-workouts/ranking">
<i class="fas fa-star"></i>Show Only Ranking Pieces
</a>
{% endif %}
</p>
</li>
<li class="maxheight grid_4">
{% if workouts %} {% if workouts %}
<table width="100%" class="listtable shortpadded"> <table width="100%" class="listtable shortpadded">
@@ -115,7 +167,6 @@
<th> Max HR </th> <th> Max HR </th>
{% if not team %} {% if not team %}
<th> &nbsp;</th> <th> &nbsp;</th>
<th> &nbsp;</th>
{% else %} {% else %}
<th colspan="2"> <th colspan="2">
Owner Owner
@@ -164,11 +215,7 @@
<td> {{ workout.duration |durationprint:"%H:%M:%S.%f" }} </td> <td> {{ workout.duration |durationprint:"%H:%M:%S.%f" }} </td>
<td> {{ workout.averagehr }} </td> <td> {{ workout.averagehr }} </td>
<td> {{ workout.maxhr }} </td> <td> {{ workout.maxhr }} </td>
{% if not team %} {% if team %}
<td>
<a class="small" href="/rowers/workout/{{ workout.id }}/export">Export</a>
</td>
{% else %}
<td colspan="2"> <td colspan="2">
<a class="small" href="/rowers/{{ workout.user.id }}/list-workouts"> <a class="small" href="/rowers/{{ workout.user.id }}/list-workouts">
{{ workout.user.user.first_name }} {{ workout.user.user.first_name }}
@@ -178,7 +225,7 @@
{% endif %} {% endif %}
<td> <a class="small" href="/rowers/workout/{{ workout.id }}/flexchart">Flex</a> </td> <td> <a class="small" href="/rowers/workout/{{ workout.id }}/flexchart">Flex</a> </td>
<td> <td>
<a class="small" href="/rowers/workout/{{ workout.id }}/deleteconfirm">Delete <a class="small" href="/rowers/workout/{{ workout.id }}/delete">Delete
</td> </td>
</tr> </tr>
@@ -189,140 +236,26 @@
{% else %} {% else %}
<p> No workouts found </p> <p> No workouts found </p>
{% endif %} {% endif %}
</div> </li>
<div class="grid_4 omega">
{% if team %}
<div class="grid_4" id="teambuttons">
<div class="grid_3 alpha">
<p>
&nbsp;
</p>
</div>
</div>
{% endif %}
<div class="grid_4" id="interactiveplot">
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
<script async="true" type="text/javascript">
Bokeh.set_log_level("info");
</script>
{{ interactiveplot |safe }}
<script>
// Set things up to resize the plot on a window resize. You can play with
// the arguments of resize_width_height() to change the plot's behavior.
var plot_resize_setup = function () {
var plotid = Object.keys(Bokeh.index)[0]; // assume we have just one plot
var plot = Bokeh.index[plotid];
var plotresizer = function() {
// arguments: use width, use height, maintain aspect ratio
plot.resize_width_height(true, true, true);
};
window.addEventListener('resize', plotresizer);
plotresizer();
};
window.addEventListener('load', plot_resize_setup);
</script>
<style>
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
html, body {height: 100%; margin:5px;}
</style>
{{ the_div |safe }}
</div>
<div class="grid_4" id="announcements">
{% if announcements %} {% if announcements %}
<li class="grid_4">
<h3>What's New?</h3> <h3>What's New?</h3>
</li>
{% for a in announcements %} {% for a in announcements %}
<li>
<div class="site-announcement-box"> <div class="site-announcement-box">
<div class="site-announcement"> <div class="site-announcement">
<i>{{ a.created }}:</i> <em>{{ a.created }}:</em>
{{ a.announcement|urlize }} {{ a.announcement|urlize }}
</div> </div>
</div> </div>
</li>
{% endfor %} {% endfor %}
<p>&nbsp;</p>
{% endif %} {% endif %}
</div> </ul>
<div class="grid_4" id="about">
<h3>About</h3>
<p>This site is a beta site, pioneering rowing data
visualization and analysis. No warranties. The site's author is
Sander Roosendaal. A Masters rower.
Read his <a href="http://blog.rowsandall.com/">blog</a> {% endblock %}
</p>
<p><a href="/rowers/email/">&copy; Rowsandall s.r.o.</a></p>
<div style="text-align: right; padding: 2em">
<a href="http://blog.rowsandall.com/">
<img src="/static/img/sander.jpg" width="80"></a>
</div>
</div>
</div>
</div>
</div>
{% block sidebar %}
<div class="grid_6 alpha"> {% include 'menu_workouts.html' %}
{% if rankingonly and not team %} {% endblock %}
<div class="grid_2 alpha">
<a class="button small green" href="/rowers/list-workouts">All Workouts</a>
</div>
{% elif not team %}
<div class="grid_2 alpha">
<a class="button small green" href="/rowers/list-workouts/ranking">Ranking Pieces Only</a>
</div>
{% endif %}
<div class="grid_2">
{% if user|is_promember %}
<a class="button small gray" href="/rowers/workouts-join-select">Glue Workouts</a>
{% else %}
<a class="button blue small" href="/rowers/promembership">Glue</a>
{% endif %}
</div>
<div class="grid_2 omega">
<a class="button small gray" href="/rowers/update_empower">Empower Repair</a>
</div>
<p>&nbsp;</p>
{% if team %}
<form id="searchform" action="/rowers/list-workouts/team/{{ team.id }}/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}"
method="get" accept-charset="utf-8">
{% else %}
<form id="searchform" action="/rowers/list-workouts/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}"
method="get" accept-charset="utf-8">
{% endif %}
<div class="grid_3 prefix_1 alpha">
<input class="searchfield" id="searchbox" name="q" type="text" placeholder="Search">
</div>
<div class="grid_1 omega">
<button class="button blue small" type="submit">
Search
</button>
</div>
</form>
</div>
<div class="grid_2 omega">
<span class="button gray small">
{% if workouts.has_previous %}
{% if request.GET.q %}
<a class="wh" href="?page={{ workouts.previous_page_number }}&q={{ request.GET.q }}">&lt;</a>
{% else %}
<a class="wh" href="?page={{ workouts.previous_page_number }}">&lt;</a>
{% endif %}
{% endif %}
<span>
Page {{ workouts.number }} of {{ workouts.paginator.num_pages }}.
</span>
{% if workouts.has_next %}
{% if request.GET.q %}
<a class="wh" href="/rowers/list-workouts/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}?page={{ workouts.next_page_number }}&q={{ request.GET.q }}">&gt;</a>
{% else %}
<a class="wh" href="/rowers/list-workouts/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}?page={{ workouts.next_page_number }}">&gt;</a>
{% endif %}
{% endif %}
</span>
{% endblock %}
+13 -13
View File
@@ -1,4 +1,4 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% load tz %} {% load tz %}
@@ -35,10 +35,10 @@ $('#id_workouttype').change();
</script> </script>
{% endblock %} {% endblock %}
{% block content %} {% block main %}
<div class="grid_12 alpha"> <h1>Add Workout Manually</h1>
<h1>Add Workout Manually</h1> <ul class="main-content">
<div class="grid_6 alpha"> <li class="grid_2">
{% if form.errors %} {% if form.errors %}
<p style="color: red;"> <p style="color: red;">
Please correct the error{{ form.errors|pluralize }} below. Please correct the error{{ form.errors|pluralize }} below.
@@ -51,17 +51,17 @@ $('#id_workouttype').change();
{{ form.as_table }} {{ form.as_table }}
</table> </table>
{% csrf_token %} {% csrf_token %}
<div id="formbutton" class="grid_1 suffix_1 omega"> <p>
<input class="button green" type="submit" value="Save"> <input class="button green" type="submit" value="Save">
</div> </p>
</form> </form>
</div> </li>
</ul>
<div id="images" class="grid_6 omega">
<p>&nbsp;</p>
</div>
</div>
{% endblock %}
{% block sidebar %}
{% include 'menu_workouts.html' %}
{% endblock %} {% endblock %}
+13 -47
View File
@@ -1,10 +1,10 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}{{ workout.name }} {% endblock %} {% block title %}{{ workout.name }} {% endblock %}
{% block content %} {% block main %}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
@@ -12,58 +12,24 @@
</script> </script>
<script> <h1>{{ workout.name }}</h1>
// Set things up to resize the plot on a window resize. You can play with
// the arguments of resize_width_height() to change the plot's behavior.
var plot_resize_setup = function () {
var plotid = Object.keys(Bokeh.index)[0]; // assume we have just one plot
var plot = Bokeh.index[plotid];
var plotresizer = function() {
// arguments: use width, use height, maintain aspect ratio
plot.resize_width_height(true, false, false);
};
window.addEventListener('resize', plotresizer);
plotresizer();
};
window.addEventListener('load', plot_resize_setup);
</script>
<style>
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
html, body, #mymap {height: 100%; margin:5px;}
</style>
<ul class="main-content">
<div id="workouts" class="grid_12 alpha"> <li class="grid_4">
<div style="height:100%;" id="theplot" class="flexplot mapdiv">
{% if user.is_authenticated and mayedit %}
<div class="grid_2 alpha">
<p>
<a class="button gray small" href="/rowers/workout/{{ workout.id }}/edit">Edit Workout</a>
</p>
</div>
<div class="grid_2">
<p>
<a class="button gray small" href="/rowers/workout/{{ workout.id }}/workflow">Workflow View</a>
</p>
</div>
<div class="grid_2 omega">
<p>
<a class="button gray small" href="/rowers/workout/{{ workout.id }}/advanced">Advanced Edit</a>
</p>
</div>
{% endif %}
</div>
<div style="height:100%;" id="theplot" class="grid_12 alpha flexplot">
{{ mapdiv|safe }} {{ mapdiv|safe }}
{{ mapscript|safe }} {{ mapscript|safe }}
</div> </li>
</ul>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_workout.html' %}
{% endblock %}
+38 -10
View File
@@ -1,3 +1,5 @@
{% load staticfiles %}
{% load rowerfilters %}
<h1>Analysis</h1> <h1>Analysis</h1>
<ul class="cd-accordion-menu animated"> <ul class="cd-accordion-menu animated">
<li class="has-children" id="fitness"> <li class="has-children" id="fitness">
@@ -6,22 +8,22 @@
<i class="fas fa-watch-fitness fa-fw"></i>&nbsp;Fitness</label> <i class="fas fa-watch-fitness fa-fw"></i>&nbsp;Fitness</label>
<ul> <ul>
<li id="fitness-ranking"> <li id="fitness-ranking">
<a href=""> <a href="/rowers/ote-bests2">
<i class="fas fa-star fa-fw"></i>&nbsp;Ranking Pieces <i class="fas fa-star fa-fw"></i>&nbsp;Ranking Pieces
</a> </a>
</li> </li>
<li id="fitness-otecp"> <li id="fitness-otecp">
<a href=""> <a href="/rowers/ote-ranking">
<i class="fas fa-user-chart fa-fw"></i>&nbsp;CP Chart OTE <i class="fas fa-user-chart fa-fw"></i>&nbsp;CP Chart OTE
</a> </a>
</li> </li>
<li id="fitness-otwcp"> <li id="fitness-otwcp">
<a href=""> <a href="/rowers/otw-bests">
<i class="far fa-user-chart fa-fw"></i>&nbsp;CP Chart OTW <i class="far fa-user-chart fa-fw"></i>&nbsp;CP Chart OTW
</a> </a>
</li> </li>
<li id="fitness-powerprogress"> <li id="fitness-powerprogress">
<a href=""> <a href="/rowers/fitnessprogress">
<i class="far fa-watch-fitness fa-fw"></i>&nbsp;Power Progress <i class="far fa-watch-fitness fa-fw"></i>&nbsp;Power Progress
</a> </a>
</li> </li>
@@ -34,34 +36,60 @@
</label> </label>
<ul> <ul>
<li id="stats-boxchart"> <li id="stats-boxchart">
<a href=""> <a href="/rowers/user-boxplot-select">
<i class="fas fa-box-open fa-fw"></i>&nbsp;Box Chart <i class="fas fa-box-open fa-fw"></i>&nbsp;Box Chart
</a> </a>
</li> </li>
<li id="stats-trendflex"> <li id="stats-trendflex">
<a href=""> <a href="/rowers/user-multiflex-select">
<i class="far fa-chart-line fa-fw"></i>&nbsp;Trend Flex <i class="far fa-chart-line fa-fw"></i>&nbsp;Trend Flex
</a> </a>
</li> </li>
<li id="stats-cumstats"> <li id="stats-cumstats">
<a href=""> <a href="/rowers/cumstats">
<i class="fal fa-table fa-fw"></i>&nbsp;Statistics <i class="fal fa-table fa-fw"></i>&nbsp;Statistics
</a> </a>
</li> </li>
<li id="stats-histopower"> <li id="stats-histopower">
<a href=""> <a href="/rowers/histo">
<i class="fas fa-chart-bar"></i>&nbsp;Power Histogram <i class="fas fa-chart-bar"></i>&nbsp;Power Histogram
</a> </a>
</li> </li>
</ul> </ul>
</li> </li>
<li> <li>
<a href=""> <a href="/rowers/flexall">
<i class="fas fa-chart-line fa-fw"></i>&nbsp;Cumulative Flex Chart <i class="fas fa-chart-line fa-fw"></i>&nbsp;Cumulative Flex Chart
</a> </a>
</li> </li>
<li> <li>
<a href=""> <a href="/rowers/laboratory">
<i class="fas fa-flask fa-fw"></i>&nbsp;Laboratory</a> <i class="fas fa-flask fa-fw"></i>&nbsp;Laboratory</a>
</li> </li>
</ul><!-- cd-accordion-menu --> </ul><!-- cd-accordion-menu -->
{% if user.is_authenticated and user|is_manager %}
<p>&nbsp;</p>
{% if user|team_members %}
<ul class="cd-accordion-menu animated">
<li class="has-children" id="athletes">
<input type="checkbox" name="athlete-selector" id="athlete-selector">
<label for="athlete-selector"><i class="fas fa-users fa-fw"></i>&nbsp;Athletes</label>
<ul>
{% for member in user|team_members %}
<a href={{ request.path|userurl:member }}>
<i class="fas fa-user fa-fw"></i>
{% if member == rower.user %}
&bull;
{% else %}
&nbsp;
{% endif %}
{{ member.first_name }} {{ member.last_name }}
</a>
{% endfor %}
</ul>
</li>
</ul>
{% endif %}
{% endif %}
+1
View File
@@ -1,3 +1,4 @@
<h1>Demo</h1>
<ul class="cd-accordion-menu animated"> <ul class="cd-accordion-menu animated">
<li><a href="#0">Link</a></li> <li><a href="#0">Link</a></li>
<li class="has-children"> <li class="has-children">
+6 -6
View File
@@ -1,23 +1,23 @@
<h1>Help</h1> <h1>Help</h1>
<ul class="cd-accordion-menu animated"> <ul class="cd-accordion-menu animated">
<li id="gettingstarted"> <li id="gettingstarted">
<a href=""> <a href="/rowers/help">
<i class="fas fa-question-circle fa-fw"></i>&nbsp;Getting Started <i class="fas fa-question-circle fa-fw"></i>&nbsp;Getting Started
</a> </a>
</li> </li>
<li id="blog"> <li id="blog">
<a href=""> <a href="analytics.rowsandall.com">
<i class="fab fa-wordpress-simple fa-fw"></i>&nbsp;Blog <i class="fab fa-wordpress-simple fa-fw"></i>&nbsp;Blog
</a> </a>
</li> </li>
<li id="contact"> <li id="contact">
<a href=""> <a href="/rowers/email">
<i class="fas fa-envelope fa-fw"></i>&nbsp;Contact <i class="fas fa-envelope fa-fw"></i>&nbsp;Contact
</a> </a>
</li> </li>
<li id="videos"> <li id="facebook">
<a href=""> <a href="https://www.facebook.com/rowsandall">
<i class="fab fa-youtube fa-fw"></i>&nbsp;Videos <i class="fab fa-facebook-square fa-fw"></i>&nbsp;Facebook group
</a> </a>
</li> </li>
</ul><!-- cd-accordion-menu --> </ul><!-- cd-accordion-menu -->
+119 -6
View File
@@ -1,5 +1,27 @@
{% load staticfiles %}
{% load rowerfilters %}
<h1>Plan</h1> <h1>Plan</h1>
<ul class="cd-accordion-menu animated"> <ul class="cd-accordion-menu animated">
<li class="has-children" id="plans">
<input type="checkbox" name="group-plans" id="group-plans">
<label for="group-plans">
<i class="fas fa-bullseye-pointer"></i>&nbsp;Plans
</label>
<ul>
<li id="plans-manage">
<a href="/rowers/createplan/">
<i class="fas fa-bullseye-pointer"></i>&nbsp;Manage Plans
</a>
</li>
{% for plan in rower|trainingplans %}
<li id="plan-{{ plan.id }}">
<a href="/rowers/plan/{{ plan.id }}/">
<i class="fal fa-calendar-alt fa-fw"></i>&nbsp;{{ plan.name }}
</a>
</li>
{% endfor %}
</ul>
</li>
<li class="has-children" id="sessions"> <li class="has-children" id="sessions">
<input type="checkbox" name="group-sessions" id="group-sessions"> <input type="checkbox" name="group-sessions" id="group-sessions">
<label for="group-sessions"> <label for="group-sessions">
@@ -7,20 +29,25 @@
</label> </label>
<ul> <ul>
<li id="sessions-list"> <li id="sessions-list">
<a href=""> <a href="/rowers/sessions/">
<i class="far fa-calendar-alt fa-fw"></i>&nbsp;Sessions <i class="far fa-calendar-alt fa-fw"></i>&nbsp;Sessions
</a> </a>
</li> </li>
<li id="sessions-link"> <li id="sessions-link">
<a href=""> <a href="/rowers/sessions/manage/">
<i class="fas fa-tasks fa-fw"></i>&nbsp;Link Workouts <i class="fas fa-tasks fa-fw"></i>&nbsp;Link Workouts
</a> </a>
</li> </li>
<li id="sessions-coach"> <li id="sessions-coach">
<a href=""> <a href="/rowers/sessions/coach/">
<i class="fas fa-bullhorn fa-fw"></i>&nbsp;Coach View <i class="fas fa-bullhorn fa-fw"></i>&nbsp;Coach View
</a> </a>
</li> </li>
<li id="sessions-print">
<a href="/rowers/sessions/print/">
<i class="fas fa-print fa-fw"></i>&nbsp;Print View
</a>
</li>
</ul> </ul>
</li> </li>
<li class="has-children" id="plan"> <li class="has-children" id="plan">
@@ -30,20 +57,106 @@
</label> </label>
<ul> <ul>
<li id="plan-session"> <li id="plan-session">
<a href=""> <a href="/rowers/sessions/create/">
<i class="far fa-calendar-plus fa-fw"></i>&nbsp;Add Session <i class="far fa-calendar-plus fa-fw"></i>&nbsp;Add Session
</a> </a>
</li> </li>
<li id="plan-teamsession"> <li id="plan-teamsession">
<a href=""> <a href="/rowers/sessions/teamcreate/">
<i class="fas fa-whistle fa-fw"></i>&nbsp;Add Team Session <i class="fas fa-whistle fa-fw"></i>&nbsp;Add Team Session
</a> </a>
</li> </li>
<li id="plan-microcycle"> <li id="plan-microcycle">
<a href=""> <a href="/rowers/sessions/multicreate/">
<i class="fas fa-expand fa-fw"></i>Plan Microcycle <i class="fas fa-expand fa-fw"></i>Plan Microcycle
</a> </a>
</li> </li>
</ul> </ul>
</li> </li>
</ul><!-- cd-accordion-menu --> </ul><!-- cd-accordion-menu -->
<p>&nbsp;</p>
<ul class="cd-accordion-menu animated">
<li class="has-children" id="cycles">
<input type="checkbox" name="cycle-selector" id="cycle-selector">
<label for="cycle-selector"><i class="far fa-calendar-alt fa-fw"></i>&nbsp;Select Time Period</label>
<ul>
<li class="has-children" id="cycles-this">
<input type="checkbox" name="cycle-this" id="cycle-this">
<label for="cycle-this">This</label>
<ul>
<li>
<a href = {{ request.path|timeurl:"thisweek" }}>
Week
</a>
</li>
<li>
<a href = {{ request.path|timeurl:"thismonth" }}>
Month
</a>
</li>
</ul>
</li>
<li class="has-children" id="cycles-next">
<input type="checkbox" name="cycle-next" id="cycle-next">
<label for="cycle-next">Next</label>
<ul>
<li>
<a href = {{ request.path|timeurl:"nextweek" }}>
Week
</a>
</li>
<li>
<a href = {{ request.path|timeurl:"nextmonth" }}>
Month
</a>
</li>
</ul>
</li>
<li class="has-children" id="cycles-Last">
<input type="checkbox" name="cycle-Last" id="cycle-Last">
<label for="cycle-Last">Last</label>
<ul>
<li>
<a href = {{ request.path|timeurl:"lastweek" }}>
Week
</a>
</li>
<li>
<a href = {{ request.path|timeurl:"lastmonth" }}>
Month
</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
{% if user.is_authenticated and user|is_manager %}
<p>&nbsp;</p>
{% if user|team_members %}
<ul class="cd-accordion-menu animated">
<li class="has-children" id="athletes">
<input type="checkbox" name="athlete-selector" id="athlete-selector">
<label for="athlete-selector"><i class="fas fa-users fa-fw"></i>&nbsp;Athletes</label>
<ul>
{% for member in user|team_members %}
<a href={{ request.path|userurl:member }}?when={{ timeperiod }}>
<i class="fas fa-user fa-fw"></i>
{% if member == rower.user %}
&bull;
{% else %}
&nbsp;
{% endif %}
{{ member.first_name }} {{ member.last_name }}
</a>
{% endfor %}
</ul>
</li>
</ul>
{% endif %}
{% endif %}
+43 -7
View File
@@ -1,19 +1,55 @@
{% load staticfiles %}
{% load rowerfilters %}
<h1>Profile</h1> <h1>Profile</h1>
<ul class="cd-accordion-menu animated"> <ul class="cd-accordion-menu animated">
<li id="manage-account"> <li id="manage-prefs">
<a href=""> <a href="/rowers/me/preferences/">
<i class="fas fa-user fa-fw"></i>&nbsp;Account <i class="fas fa-cog fa-fw"></i>&nbsp;Zones
</a> </a>
</li> </li>
<li id="manage-impex"> <li id="manage-impex">
<a href=""> <a href="/rowers/me/exportsettings/">
<i class="fas fa-cloud-download fa-fw"></i>&nbsp;Import/Export <i class="fas fa-cloud-download fa-fw"></i>&nbsp;Import/Export
</a> </a>
</li> </li>
<li id="manage-prefs"> <li id="manage-account">
<a href=""> <a href="/rowers/me/edit/">
<i class="fas fa-cog fa-fw"></i>&nbsp;Preferences <i class="fas fa-user fa-fw"></i>&nbsp;Account
</a>
</li>
<li id="manage-favs">
<a href="/rowers/me/favoritecharts/">
<i class="fas fa-chart-area fa-fw"></i>&nbsp;Favorite Charts
</a>
</li>
<li id="manage-workflow">
<a href="/rowers/me/workflowconfig2/">
<i class="fas fa-tachometer-alt-slow fa-fw"></i>&nbsp;Manage Workflow
</a> </a>
</li> </li>
</ul><!-- cd-accordion-menu --> </ul><!-- cd-accordion-menu -->
{% if user.is_authenticated and user|is_manager %}
<p>&nbsp;</p>
{% if user|team_members %}
<ul class="cd-accordion-menu animated">
<li class="has-children" id="athletes">
<input type="checkbox" name="athlete-selector" id="athlete-selector">
<label for="athlete-selector"><i class="fas fa-users fa-fw"></i>&nbsp;Athletes</label>
<ul>
{% for member in user|team_members %}
<a href={{ request.path|userurl:member }}>
<i class="fas fa-user fa-fw"></i>
{% if member == rower.user %}
&bull;
{% else %}
&nbsp;
{% endif %}
{{ member.first_name }} {{ member.last_name }}
</a>
{% endfor %}
</ul>
</li>
</ul>
{% endif %}
{% endif %}
+41 -3
View File
@@ -1,18 +1,56 @@
<h1>Racing</h1> <h1>Racing</h1>
<ul class="cd-accordion-menu animated"> <ul class="cd-accordion-menu animated">
<li id="races-list"> <li id="races-list">
<a href="#0"> <a href="/rowers/virtualevents">
<i class="fas fa-flag-checkered fa-fw"></i>&nbsp;Races <i class="fas fa-flag-checkered fa-fw"></i>&nbsp;Races
</a> </a>
</li> </li>
<li id="races-new"> <li id="races-new">
<a href="#0"> <a href="/rowers/virtualevent/create">
<i class="far fa-flag fa-fw"></i>&nbsp;New Race <i class="far fa-flag fa-fw"></i>&nbsp;New Race
</a> </a>
</li> </li>
<li id="courses"> <li id="courses">
<a href="#0"> <a href="/rowers/list-courses">
<i class="fas fa-map-marked fa-fw"></i>&nbsp;Courses <i class="fas fa-map-marked fa-fw"></i>&nbsp;Courses
</a> </a>
</li> </li>
{% if course %}
<li class="has-children" id="course">
<input type="checkbox" name="group-course" id="group-course" checked>
<label for="group-course"><i class="fas fa-map-marked fa-fw"></i>&nbsp;{{ course.name }}</label>
<ul>
<li id="course-view">
<a href="/rowers/courses/{{ course.id }}">
<i class="fas fa-search fa-fw"></i>&nbsp;View
</a>
</li>
<li id="course-mapview">
<a href="/rowers/courses/{{ course.id }}/map">
<i class="fas fa-map fa-fw"></i>&nbsp;Map View
</a>
</li>
{% if course.manager == rower %}
<li id="course-emailkml">
<a href="/rowers/courses/{{ course.id }}/emailkml">
<i class="fas fa-envelope fa-fw"></i>&nbsp;Export as KML</a>
</li>
<li id="course-editview">
<a href="/rowers/courses/{{ course.id }}/edit">
<i class="fas fa-pencil-alt fa-fw"></i>&nbsp;Edit</a>
</li>
{% if nosessions %}
<li id="course-deleteview">
<a href="/rowers/courses/{{ course.id }}/delete">
<i class="fas fa-trash-alt fa-fw"></i>&nbsp;Delete</a>
</li>
{% endif %}
<li id="course-view">
<a href="/rowers/courses/{{ course.id }}/replace">
<i class="fas fa-map-marked-alt fa-fw"></i>&nbsp;Update Markers</a>
</li>
{% endif %}
</ul>
</li>
{% endif %}
</ul> <!-- cd-accordion-menu --> </ul> <!-- cd-accordion-menu -->
+84 -14
View File
@@ -1,24 +1,94 @@
{% load staticfiles %}
{% load rowerfilters %}
<h1>Teams</h1> <h1>Teams</h1>
<ul class="cd-accordion-menu animated"> <ul class="cd-accordion-menu animated">
<li id="manage"> <li id="manage">
<a href=""> <a href="/rowers/me/teams">
<i class="fas fa-cog fa-fw"></i>&nbsp;Manage <i class="fas fa-cog fa-fw"></i>&nbsp;Overview
</a> </a>
</li> </li>
{% if teams %} {% if user|is_manager %}
<li class="has-children" id="teams"> <li id="create">
<input type="checkbox" name="group-teams" id="group-teams"> <a href="/rowers/team/create">
<label for="group-teams">Teams</label> <i class="fas fa-plus fa-fw"></i>&nbsp;New Team
<ul>
{% for team in teams %}
<li id="team-{{ team.id }}">
<a href="">
<i class="fas fa-user-friends fa-fw"></i>&nbsp;{{ team.name }}
</a> </a>
</li> </li>
{% endfor %}
</ul>
</li>
{% endif %} {% endif %}
</ul><!-- cd-accordion-menu --> </ul><!-- cd-accordion-menu -->
{% if myteams %}
<h2>Managing</h2>
<ul class="cd-accordion-menu animated">
{% for team in myteams %}
<li class="has-children" id="team-{{ team.id }}">
<input type="checkbox" name="group-team-{{ team.id }}" id="group-team-{{ team.id }}">
<label for="group-team-{{ team.id }}">{{ team.name }}</label>
<ul>
<li id="team-{{ team.id }}-view">
<a href="/rowers/team/{{ team.id }}">
<i class="fas fa-user-friends fa-fw"></i>&nbsp;View
</a>
</li>
<li id="team-{{ team.id }}-edit">
<a href="/rowers/team/{{ team.id }}/edit">
<i class="fas fa-user-friends fa-fw"></i>&nbsp;Edit
</a>
</li>
<li id="team-{{ team.id }}-stats">
<a href="/rowers/team/{{ team.id }}/memberstats">
<i class="fas fa-pencil-alt fa-fw"></i>&nbsp;Member Stats
</a>
</li>
<li id="team-{{ team.id }}-workouts">
<a href="/rowers/list-workouts/team/{{ team.id }}/">
<i class="fas fa-clipboard-list fa-fw"></i>&nbsp;Member Workouts
</a>
</li>
<li id="team-{{ team.id }}-leave">
<a href="/rowers/team/{{ team.id }}/leaveconfirm">
<i class="fas fa-sign-out fa-fw"></i>&nbsp;Leave
</a>
</li>
<li id="team-{{ team.id }}-delete">
<a href="/rowers/team/{{ team.id }}/deleteconfirm">
<i class="fas fa-trash fa-fw"></i>&nbsp;Delete
</a>
</li>
</ul>
</li>
{% endfor %}
</ul>
{% endif %}
{% if memberteams %}
<h2>Member</h2>
<ul class="cd-accordion-menu animated">
{% for team in memberteams %}
<li class="has-children" id="team-{{ team.id }}">
<input type="checkbox" name="group-team-{{ team.id }}" id="group-team-{{ team.id }}">
<label for="group-team-{{ team.id }}">{{ team.name }}</label>
<ul>
<li id="team-{{ team.id }}-view">
<a href="/rowers/team/{{ team.id }}">
<i class="fas fa-user-friends fa-fw"></i>&nbsp;View
</a>
</li>
<li id="team-{{ team.id }}-workouts">
<a href="/rowers/list-workouts/team/{{ team.id }}/">
<i class="fas fa-clipboard-list fa-fw"></i>&nbsp;Member Workouts
</a>
</li>
<li id="team-{{ team.id }}-leave">
<a href="/rowers/team/{{ team.id }}/leaveconfirm">
<i class="fas fa-sign-out fa-fw"></i>&nbsp;Leave
</a>
</li>
</ul>
</li>
{% endfor %}
</ul>
{% endif %}
+183 -29
View File
@@ -1,3 +1,4 @@
{% load rowerfilters %}
<h1>Workout</h1> <h1>Workout</h1>
<ul class="cd-accordion-menu animated"> <ul class="cd-accordion-menu animated">
<li class="has-children" id="workout"> <li class="has-children" id="workout">
@@ -5,81 +6,231 @@
<label for="group-workout">Workout</label> <label for="group-workout">Workout</label>
<ul> <ul>
<li id="workout-dashboard"> <li id="workout-dashboard">
<a href=""> {% if user.is_authenticated and workout|may_edit:request %}
<a href="/rowers/workout/{{ workout.id }}/workflow">
<i class="fas fa-tachometer-alt fa-fw"></i>&nbsp;View <i class="fas fa-tachometer-alt fa-fw"></i>&nbsp;View
</a> </a>
{% else %}
<a href="/rowers/workout/{{ workout.id }}/workflow">
<i class="fas fa-tachometer-alt fa-fw"></i>&nbsp;View
</a>
{% endif %}
</li> </li>
{% if user.is_authenticated and workout|may_edit:request %}
<li id="workout-edit"> <li id="workout-edit">
<a href=""> <a href="/rowers/workout/{{ workout.id }}/edit">
<i class="fas fa-pencil-alt fa-fw"></i>&nbsp;Edit <i class="fas fa-pencil-alt fa-fw"></i>&nbsp;Edit
</a> </a>
</li> </li>
<li id="workout-intervals"> <li id="workout-intervals">
<a href=""> <a href="/rowers/workout/{{ workout.id }}/editintervals">
<i class="fas fa-pause fa-fw"></i>&nbsp;Intervals <i class="fas fa-pause fa-fw"></i>&nbsp;Intervals
</a> </a>
</li> </li>
{% endif %}
{% if user.is_authenticated %}
<li id="workout-comments">
<a href="/rowers/workout/{{ workout.id }}/comment">
<i class="fas fa-comments fa-fw"></i>&nbsp;Comments
({{ workout|aantalcomments }})
</a>
</li>
{% endif %}
<li id="workout-stats"> <li id="workout-stats">
<a href=""> <a href="/rowers/workout/{{ workout.id }}/stats">
<i class="fal fa-table fa-fw"></i>&nbsp;Statistics <i class="fal fa-table fa-fw"></i>&nbsp;Statistics
</a> </a>
</li> </li>
<li id="compare"> <li id="compare">
<a href="#0"> <a href="/rowers/multi-compare">
<i class="fas fa-balance-scale fa-fw"></i>&nbsp;Compare <i class="fas fa-balance-scale fa-fw"></i>&nbsp;Compare
</a> </a>
</li> </li>
{% if user.is_authenticated and workout|may_edit:request %}
<li id="workout-delete"> <li id="workout-delete">
<a href=""> <a href="/rowers/workout/{{ workout.id }}/delete">
<i class="fas fa-trash-alt fa-fw"></i>&nbsp;Delete <i class="fas fa-trash-alt fa-fw"></i>&nbsp;Delete
</a> </a>
</li> </li>
{% endif %}
</ul> </ul>
</li> </li>
<li class="has-children" id="flexchart">
<input type="checkbox" name="group-flexchart" id="group-flexchart">
<label for="group-flexchart">Interactive Charts</label>
<ul>
<li id="chart-flexchart">
<a href="/rowers/workout/{{ workout.id }}/flexchart">
<i class="fas fa-chart-line fa-fw"></i>&nbsp;Flex Chart
</a>
</li>
{% if workout|water %}
<li id="chart-map">
<a href="/rowers/workout/{{ workout.id }}/map">
<i class="fas fa-map-marked-alt fa-fw"></i>&nbsp;Map
</a>
</li>
<li id="chart-empower">
<a href="/rowers/workout/{{ workout.id }}/forcecurve">
<i class="fas fa-dumbbell fa-fw"></i>&nbsp;Force Curve
</a>
</li>
<li id="chart-otwpower">
<a href="/rowers/workout/{{ workout.id }}/interactiveotwplot">
<i class="fal fa-calculator-alt fa-fw"></i>&nbsp;OTW Power
</a>
</li>
{% endif %}
</ul>
</li>
{% if user.is_authenticated and workout|may_edit:request %}
<li class="has-children" id="chart"> <li class="has-children" id="chart">
<input type="checkbox" name="group-chart" id="group-chart"> <input type="checkbox" name="group-chart" id="group-chart">
<label for="group-chart">Charts</label> <label for="group-chart">Static Charts</label>
<ul> <ul>
<li id="chart-time"> <li id="chart-time">
<a href=""> <a href="/rowers/workout/{{ workout.id }}/addstatic/1">
<i class="fas fa-stopwatch fa-fw"></i>&nbsp;Time <i class="fas fa-stopwatch fa-fw"></i>&nbsp;Time
</a> </a>
</li> </li>
<li id="chart-distance"> <li id="chart-distance">
<a href=""> <a href="/rowers/workout/{{ workout.id }}/addstatic/2">
<i class="fas fa-ruler fa-fw"></i>&nbsp;Distance <i class="fas fa-ruler fa-fw"></i>&nbsp;Distance
</a> </a>
</li> </li>
<li id="chart-powerpie"> <li id="chart-powerpie">
<a href=""> <a href="/rowers/workout/{{ workout.id }}/addstatic/13">
<i class="far fa-chart-pie fa-fw"></i>&nbsp;Power (Pie) <i class="far fa-chart-pie fa-fw"></i>&nbsp;Power (Pie)
</a> </a>
</li> </li>
<li id="chart-hrpie"> <li id="chart-hrpie">
<a href=""> <a href="/rowers/workout/{{ workout.id }}/addstatic/3">
<i class="fas fa-heartbeat fa-fw"></i>&nbsp;Heart Rate (Pie) <i class="fas fa-heartbeat fa-fw"></i>&nbsp;Heart Rate (Pie)
</a> </a>
</li> </li>
{% if workout|water %}
<li id="chart-otwpower"> <li id="chart-otwpower">
<a href=""> <a href="/rowers/workout/{{ workout.id }}/addstatic/9">
<i class="fas fa-chart-area fa-fw"></i>&nbsp;OTW Power <i class="fas fa-chart-area fa-fw"></i>&nbsp;OTW Power
</a> </a>
</li> </li>
{% endif %}
<li id="chart-image">
<a href="/rowers/workout/{{ workout.id }}/image">
<i class="fas fa-file-image fa-fw"></i>&nbsp;Upload Image
</a>
</li>
</ul> </ul>
</li> </li>
<li class="has-children" id="export"> <li class="has-children" id="export">
<input type="checkbox" name="group-export" id="group-export"> <input type="checkbox" name="group-export" id="group-export">
<label for="group-export">Export</label> <label for="group-export">Export</label>
<ul> <ul>
<li id="export-c2"><a href="">Concept2</a></li> <li id="export-c2">
<li id="export-strava"><a href="">Strava</a></li> {% if workout.uploadedtoc2 %}
<li id="export-st"><a href="">SportTracks</a></li> <a href="http://log.concept2.com/profile/{{ user|c2userid }}/log/{{ workout.uploadedtoc2 }}">
<li id="export-rk"><a href="">Runkeeper</a></li> Concept2 <i class="fas fa-check"></i>
<li id="export-mmf"><a href="">MapMyFitness</a></li> </a>
<li id="export-tp"><a href="">TrainingPeaks</a></li> {% elif user.rower.c2token == None or user.rower.c2token == '' %}
<li id="export-csv"><a href="">CSV</a></li> <a href="/rowers/me/c2authorize">
<li id="export-gpx"><a href="">GPX</a></li> Connect to Concept2
<li id="export-tcx"><a href="">TCX</a></li> </a>
{% else %}
<a href="/rowers/workout/{{ workout.id }}/c2uploadw">
Concept2
</a>
{% endif %}
</li>
<li id="export-strava">
{% if workout.uploadedtostrava %}
<a href="https://www.strava.com/activities/{{ workout.uploadedtostrava }}">
Strava <i class="fas fa-check"></i>
</a>
{% elif user.rower.stravatoken == None or user.rower.stravatoken == '' %}
<a href="/rowers/me/stravaauthorize">
Connect to Strava
</a>
{% else %}
<a href="/rowers/workout/{{ workout.id }}/stravauploadw">
Strava
</a>
{% endif %}
</li>
<li id="export-st">
{% if workout.uploadedtosporttracks %}
<a href="https://sporttracks.mobi/activity/{{ workout.uploadedtosporttracks }}">
SportTracks <i class="fas fa-check"></i>
</a>
{% elif user.rower.sporttrackstoken == None or user.rower.sporttrackstoken == '' %}
<a href="/rowers/me/sporttracksauthorize">
Connect to SportTracks
</a>
{% else %}
<a href="/rowers/workout/{{ workout.id }}/sporttracksuploadw">
SportTracks
</a>
{% endif %}
</li>
<li id="export-rk">
{% if workout.uploadedtorunkeeper %}
<a href="https://runkeeper.com/user/{{ user|rkuserid }}/activity/{{ workout.uploadedtorunkeeper }}">
Runkeeper <i class="fas fa-check"></i>
</a>
{% elif user.rower.runkeepertoken == None or user.rower.runkeepertoken == '' %}
<a href="/rowers/me/runkeeperauthorize">
Connect to Runkeeper
</a>
{% else %}
<a href="/rowers/workout/{{ workout.id }}/runkeeperuploadw">
Runkeeper
</a>
{% endif %}
</li>
<li id="export-mmf">
{% if workout.uploadedtounderarmour %}
<a href="https://www.mapmyfitness.com/workout/{{ workout.uploadedtounderarmour }}">
MapMyFitness <i class="fas fa-check"></i>
</a>
{% elif user.rower.underarmourtoken == None or user.rower.underarmourtoken == '' %}
<a href="/rowers/me/underarmourauthorize">
Connect to MapMyFitness
</a>
{% else %}
<a href="/rowers/workout/{{ workout.id }}/underarmouruploadw">
MapMyFitness
</a>
{% endif %}
</li>
<li id="export-tp">
{% if workout.uploadedtotp %}
<a href="https://app.trainingpeaks.com">
TrainingPeaks <i class="fas fa-check"></i>
</a>
{% elif user.rower.tptoken == None or user.rower.tptoken == '' %}
<a href="/rowers/me/tpauthorize">
Connect to TrainingPeaks
</a>
{% else %}
<a href="/rowers/workout/{{ workout.id }}/tpuploadw">
TrainingPeaks
</a>
{% endif %}
</li>
<li id="export-csv">
<a href="/rowers/workout/{{ workout.id }}/emailcsv">
CSV
</a>
</li>
<li id="export-gpx">
<a href="/rowers/workout/{{ workout.id }}/emailgpx">
GPX
</a>
</li>
<li id="export-tcx">
<a href="/rowers/workout/{{ workout.id }}/emailtcx">
TCX
</a>
</li>
</ul> </ul>
</li> </li>
<li class="has-children" id="data"> <li class="has-children" id="data">
@@ -87,22 +238,22 @@
<label for="group-data">Data</label> <label for="group-data">Data</label>
<ul> <ul>
<li id="data-smoothen"> <li id="data-smoothen">
<a href=""> <a href="/rowers/workout/{{ workout.id }}/smoothenpace">
<i class="fas fa-magic fa-fw"></i>&nbsp;Smoothen <i class="fas fa-magic fa-fw"></i>&nbsp;Smoothen
</a> </a>
</li> </li>
<li id="data-raw"> <li id="data-raw">
<a href=""> <a href="/rowers/workout/{{ workout.id }}/undosmoothenpace">
<i class="fas fa-undo fa-fw"></i>&nbsp;Restore Raw <i class="fas fa-undo fa-fw"></i>&nbsp;Restore Raw
</a> </a>
</li> </li>
<li id="data-fusion"> <li id="data-fusion">
<a href=""> <a href="/rowers/workout/fusion/{{ workout.id }}/">
<i class="fas fa-blender fa-fw"></i>&nbsp;Sensor Fusion <i class="fas fa-blender fa-fw"></i>&nbsp;Sensor Fusion
</a> </a>
</li> </li>
<li id="data-split"> <li id="data-split">
<a href=""> <a href="/rowers/workout/{{ workout.id }}/split">
<i class="fas fa-cut fa-fw"></i>&nbsp;Split Workout <i class="fas fa-cut fa-fw"></i>&nbsp;Split Workout
</a> </a>
</li> </li>
@@ -112,24 +263,27 @@
<input type="checkbox" name="group-advanced" id="group-advanced"> <input type="checkbox" name="group-advanced" id="group-advanced">
<label for="group-advanced">Advanced</label> <label for="group-advanced">Advanced</label>
<ul> <ul>
{% if workout|water %}
<li id="advanced-wind"> <li id="advanced-wind">
<a href=""> <a href="/rowers/workout/{{ workout.id }}/wind">
<i class="fas fa-pennant fa-fw"></i>&nbsp;Wind <i class="fas fa-pennant fa-fw"></i>&nbsp;Wind
</a> </a>
</li> </li>
<li id="advanced-stream"> <li id="advanced-stream">
<a href=""> <a href="/rowers/workout/{{ workout.id }}/stream">
<i class="fas fa-stream fa-fw"></i>&nbsp;Stream <i class="fas fa-stream fa-fw"></i>&nbsp;Stream
</a> </a>
</li> </li>
<li id="advanced-otwpower"> <li id="advanced-otwpower">
<a href=""> <a href="/rowers/workout/{{ workout.id }}/otwsetpower">
<i class="fas fa-calculator-alt fa-fw"></i>&nbsp;OTW Power <i class="fas fa-calculator-alt fa-fw"></i>&nbsp;OTW Power
</a> </a>
</li> </li>
{% endif %}
<li id="advanced-instroke"> <li id="advanced-instroke">
<a href=""> <a href="/rowers/workout/{{ workout.id }}/instroke">
<i class="fas fa-search-plus fa-fw"></i>&nbsp;In-Stroke Metrics</a></li> <i class="fas fa-search-plus fa-fw"></i>&nbsp;In-Stroke Metrics</a></li>
</ul> </ul>
</li> </li>
{% endif %}
</ul><!-- cd-accordion-menu --> </ul><!-- cd-accordion-menu -->
+45 -10
View File
@@ -1,28 +1,63 @@
{% load staticfiles %}
{% load rowerfilters %}
<h1>Workouts</h1> <h1>Workouts</h1>
<ul class="cd-accordion-menu animated"> <ul class="cd-accordion-menu animated">
<li id="workouts-list"> <li id="workouts-list">
<a href="#0"><i class="fas fa-clipboard-list fa-fw"></i>&nbsp;Workouts List</a> <a href="/rowers/list-workouts"><i class="fas fa-clipboard-list fa-fw"></i>&nbsp;Workouts List</a>
</li> </li>
<li id="charts"> <li id="charts">
<a href="#0"><i class="fas fa-chart-pie fa-fw"></i>&nbsp;Charts</a> <a href="/rowers/list-graphs"><i class="fas fa-chart-pie fa-fw"></i>&nbsp;Charts</a>
</li> </li>
<li id="compare"> <li id="compare">
<a href="#0"><i class="fas fa-balance-scale fa-fw"></i>&nbsp;Compare</a> <a href="/rowers/team-compare-select/team/0/"><i class="fas fa-balance-scale fa-fw"></i>&nbsp;Compare</a>
</li> </li>
<li> <li>
<a href="#0"><i class="fas fa-file-upload fa-fw"></i>&nbsp;Upload</a> <a href="/rowers/workout/upload/"><i class="fas fa-file-upload fa-fw"></i>&nbsp;Upload</a>
</li>
<li>
{% if user|is_promember %}
<a href="/rowers/workouts-join-select">
{% else %}
<a href="/rowers/promembership">Glue Workouts</a>
{% endif %}
<i class="fas fa-layer-plus fa-fw"></i>&nbsp;Glue Workouts
</a>
</li> </li>
<li class="has-children" id="imports"> <li class="has-children" id="imports">
<input type="checkbox" name ="group-1" id="group-1"> <input type="checkbox" name ="group-1" id="group-1">
<label for="group-1"><i class="fas fa-cloud-download fa-fw"></i>&nbsp;Import</label> <label for="group-1"><i class="fas fa-cloud-download fa-fw"></i>&nbsp;Import</label>
<ul> <ul>
<li id="concept2"><a href="#0">Concept2</a></li> <li id="concept2"><a href="/rowers/workout/c2list">Concept2</a></li>
<li id="strava"><a href="#0">Strava</a></li> <li id="strava"><a href="/rowers/workout/stravaimport">Strava</a></li>
<li id="runkeeper"><a href="#0">RunKeeper</a></li> <li id="runkeeper"><a href="/rowers/workout/runkeeperimport">RunKeeper</a></li>
<li id="sporttracks"><a href="#0">SportTracks</a></li> <li id="sporttracks"><a href="/rowers/workout/sporttracksimport">SportTracks</a></li>
<li id="mapmyfitness"><a href="#0">MapMyFitness</a></li> <li id="mapmyfitness"><a href="/rowers/workout/underarmourimport">MapMyFitness</a></li>
<li id="polar"><a href="#0">Polar</a></li> <li id="polar"><a href="/rowers/workout/polarimport">Polar</a></li>
</ul> </ul>
</li> </li>
</ul> <!-- cd-accordion-menu --> </ul> <!-- cd-accordion-menu -->
{% if user.is_authenticated and user|is_manager %}
<p>&nbsp;</p>
{% if user|team_members %|
<ul class="cd-accordion-menu animated">
<li class="has-children" id="athletes">
<input type="checkbox" name="athlete-selector" id="athlete-selector">
<label for="athlete-selector"><i class="fas fa-users fa-fw"></i>&nbsp;Athletes</label>
<ul>
{% for member in user|team_members %}
<a href={{ request.path|userurl:member }}>
<i class="fas fa-user fa-fw"></i>
{% if member == rower.user %}
&bull;
{% else %}
&nbsp;
{% endif %}
{{ member.first_name }} {{ member.last_name }}
</a>
{% endfor %}
</ul>
</li>
</ul>
{% endif %}
+17 -44
View File
@@ -1,10 +1,10 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}View Comparison {% endblock %} {% block title %}View Comparison {% endblock %}
{% block content %} {% block main %}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
@@ -13,58 +13,31 @@
{{ interactiveplot |safe }} {{ interactiveplot |safe }}
<script> <h1>Interactive Comparison</h1>
// Set things up to resize the plot on a window resize. You can play with <ul class="main-content">
// the arguments of resize_width_height() to change the plot's behavior. <li class="grid_4">
var plot_resize_setup = function () {
var plotid = Object.keys(Bokeh.index)[0]; // assume we have just one plot
var plot = Bokeh.index[plotid];
var plotresizer = function() {
// arguments: use width, use height, maintain aspect ratio
plot.resize_width_height(true, false, false);
};
window.addEventListener('resize', plotresizer);
plotresizer();
};
window.addEventListener('load', plot_resize_setup);
</script>
<div>
<style> {{ the_div|safe }}
/* Need this to get the page in "desktop mode"; not having an infinite height.*/ </div>
html, body {height: 100%; margin:5px;} </li>
</style> <li class="grid_4">
<div class="grid_12 alpha">
{% include "teambuttons.html" with teamid=teamid team=team %}
</div>
<div class="grid_12">
<div id="workouts" class="grid_8 alpha">
<h1>Interactive Comparison</h1>
</div>
<div class="grid_4 omega">
<form enctype="multipart/form-data" action="/rowers/multi-compare" method="post"> <form enctype="multipart/form-data" action="/rowers/multi-compare" method="post">
{% csrf_token %} {% csrf_token %}
<table> <table>
{{ chartform.as_table }} {{ chartform.as_table }}
</table> </table>
<div class="grid_1 prefix_2 suffix_1">
<p> <p>
<input name='workoutselectform' class="button green" type="submit" value="Submit"> <input name='workoutselectform' class="button green" type="submit" value="Submit">
</p> </p>
</div>
</form> </form>
</div> </li>
</div> </ul>
<div class="grid_12 alpha">
<div id="theplot" class="grid_12 alpha flexplot">
{{ the_div|safe }}
</div>
</div>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_workouts.html' %}
{% endblock %}
+20 -37
View File
@@ -1,10 +1,10 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}View Comparison {% endblock %} {% block title %}View Comparison {% endblock %}
{% block content %} {% block main %}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
@@ -15,58 +15,37 @@
</div> </div>
<script>
// Set things up to resize the plot on a window resize. You can play with
// the arguments of resize_width_height() to change the plot's behavior.
var plot_resize_setup = function () {
var plotid = Object.keys(Bokeh.index)[0]; // assume we have just one plot
var plot = Bokeh.index[plotid];
var plotresizer = function() {
// arguments: use width, use height, maintain aspect ratio
plot.resize_width_height(true, false, false);
};
window.addEventListener('resize', plotresizer);
plotresizer();
};
window.addEventListener('load', plot_resize_setup);
</script>
<style>
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
html, body {height: 100%; margin:5px;}
</style>
<div class="grid_12 alpha"> <h1>Trend Flex Chart</h1>
<h1>Trend Flex Chart</h1>
<div id="workouts" class="grid_8 alpha"> <ul class="main-content">
<div id="id_chart" class="grid_8 alpha flexplot"> <li class="grid_4">
<div id="id_chart" class="flexplot">
{{ the_div|safe }} {{ the_div|safe }}
</div> </div>
</div> </li>
<div class="grid_4 omega"> <li class="grid_2">
<div class="grid_4"> <form enctype="multipart/form-data" action="/rowers/user-multiflex/user/{{ userid }}" method="post">
<form enctype="multipart/form-data" action="/rowers/user-multiflex/{{ userid }}" method="post">
{% csrf_token %} {% csrf_token %}
<table> <table>
{{ chartform.as_table }} {{ chartform.as_table }}
</table> </table>
<div class="grid_1 prefix_2 suffix_1">
<p> <p>
<input name='workoutselectform' class="button green" type="submit" value="Submit"> <input name='workoutselectform' class="button green" type="submit" value="Submit">
</p> </p>
</div>
</form> </form>
</div> </li>
<div class="grid_4"> <li class="grid_2">
<p> <p>
You can use the form above to change the metric or filter the data. You can use the form to change the metric or filter the data.
Set Min SPM and Max SPM to select only strokes in a certain range of Set Min SPM and Max SPM to select only strokes in a certain range of
stroke rates. stroke rates.
Set Work per Stroke to a minimum value to remove "paddle" strokes or turns. Set Work per Stroke to a minimum value to remove "paddle" strokes or turns.
</p> </p>
</div> </li>
</div> </ul>
</div>
{% endblock %} {% endblock %}
@@ -93,3 +72,7 @@
</script> </script>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_analytics.html' %}
{% endblock %}
+39 -105
View File
@@ -1,4 +1,4 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
@@ -8,77 +8,26 @@
{% block title %}Workouts{% endblock %} {% block title %}Workouts{% endblock %}
{% block content %} {% block main %}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>
{{ interactiveplot |safe }} {{ interactiveplot |safe }}
<script> {% if theuser %}
// Set things up to resize the plot on a window resize. You can play with <h1>{{ theuser.first_name }}'s Ranking Pieces</h1>
// the arguments of resize_width_height() to change the plot's behavior. {% else %}
var plot_resize_setup = function () { <h1>{{ user.first_name }}'s Ranking Pieces</h1>
var plotid = Object.keys(Bokeh.index)[0]; // assume we have just one plot {% endif %}
var plot = Bokeh.index[plotid];
var plotresizer = function() {
// arguments: use width, use height, maintain aspect ratio
plot.resize_width_height(true, true, false);
};
window.addEventListener('resize', plotresizer);
plotresizer();
};
window.addEventListener('load', plot_resize_setup);
</script>
<style>
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
html, body {height: 100%; margin:5px;}
</style>
<ul class="main-content">
<div id="title" class="grid_12 alpha"> <li class="grid_2">
<div class="grid_10 alpha">
{% if theuser %}
<h3>{{ theuser.first_name }}'s Ranking Pieces</h3>
{% else %}
<h3>{{ user.first_name }}'s Ranking Pieces</h3>
{% endif %}
</div>
<div class="grid_2 omega">
{% if user.is_authenticated and user|is_manager %}
<div class="grid_2 alpha dropdown">
<button class="grid_2 alpha button green small dropbtn">
{{ theuser.first_name }} {{ theuser.last_name }}
</button>
<div class="dropdown-content">
{% for member in user|team_members %}
{% if workouttype == 'water' %}
<a class="button green small" href="/rowers/{{ member.id }}/otw-bests/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}">{{ member.first_name }} {{ member.last_name }}</a>
{% else %}
<a class="button green small" href="/rowers/{{ member.id }}/ote-ranking/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}">{{ member.first_name }} {{ member.last_name }}</a>
{% endif %}
{% endfor %}
</div>
{% else %}
&nbsp;
{% endif %}
</div>
</div>
<div id="summary" class="grid_6 alpha">
<p>Summary for {{ theuser.first_name }} {{ theuser.last_name }} <p>Summary for {{ theuser.first_name }} {{ theuser.last_name }}
between {{ startdate|date }} and {{ enddate|date }}</p> between {{ startdate|date }} and {{ enddate|date }}</p>
<p>Direct link for other users:
{% if workouttype == 'water' %}
<a href="/rowers/{{ id }}/otw-bests/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}">https://rowsandall.com/rowers/{{ id }}/otw-bests/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}</a>
{% else %}
<a href="/rowers/{{ id }}/ote-ranking/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}">https://rowsandall.com/rowers/{{ id }}/ote-ranking/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}</a>
{% endif %}
</p>
<p>The table gives the efforts you marked as Ranking Piece. <p>The table gives the efforts you marked as Ranking Piece.
The graph shows the best segments from those pieces, plotted as The graph shows the best segments from those pieces, plotted as
average power (over the segment) vs the duration of the segment/ average power (over the segment) vs the duration of the segment/
@@ -86,54 +35,40 @@
</p> </p>
<p>Whenever you load or reload the page, a new calculation is started <p>Whenever you load or reload the page, a new calculation is started
as a background process. The page will reload automatically when as a background process. The page will reload automatically when the
calculation is ready.</p> calculation is ready.
<p>At the bottom of the page, you will find predictions derived from the model.</p> </p>
</div>
<div id="form" class="grid_6 omega"> <p>At the bottom of the page, you will find predictions derived from the model.</p>
</li>
<li class="grid_2">
<p>Use this form to select a different date range:</p> <p>Use this form to select a different date range:</p>
<p> <p>
Select start and end date for a date range: Select start and end date for a date range:
<div class="grid_4 alpha">
<form enctype="multipart/form-data" action="" method="post"> <form enctype="multipart/form-data" action="" method="post">
<table> <table>
{{ dateform.as_table }} {{ dateform.as_table }}
</table> </table>
{% csrf_token %} {% csrf_token %}
</div> <input name='daterange' class="button green" type="submit" value="Submit">
<div class="grid_2 omega">
<input name='daterange' class="button green" type="submit" value="Submit"> </form>
</div>
<div class="grid_4 alpha">
<form enctype="multipart/form-data" action="" method="post">
Or use the last {{ deltaform }} days.
</div>
<div class="grid_2 omega">
{% csrf_token %}
<input name='datedelta' class="button green" type="submit" value="Submit">
</form> </form>
</div> </li>
</div> <li class="grid_4">
<h2>Critical Power Plot</h2>
<div id="theplot" class="grid_12 alpha">
<h2>Critical Power Plot</h2>
{{ the_div|safe }} {{ the_div|safe }}
</div> </li>
<div class="grid_12 alpha"> <li class="grid_2">
<h2>Ranking Piece Results</h2> <h2>Ranking Piece Results</h2>
{% if rankingworkouts %} {% if rankingworkouts %}
<table width="70%" class="listtable"> <table width="100%" class="listtable">
<thead> <thead>
<tr> <tr>
<th> Distance</th> <th> Distance</th>
@@ -166,17 +101,16 @@
<p> No ranking workouts found </p> <p> No ranking workouts found </p>
{% endif %} {% endif %}
</div> </li>
<div id="predictions" class="grid_12 alpha"> <li class="grid_2">
<h2>Pace predictions for Ranking Pieces</h2> <h2>Pace predictions for Ranking Pieces</h2>
<p>Add non-ranking piece using the form. The piece will be added in the prediction tables below. </p> <p>Add non-ranking piece using the form. The piece will be added in the prediction tables below. </p>
<div id="cpmodel" class="grid_6 alpha"> <table width="100%" class="listtable">
<table width="90%" class="listtable">
<thead> <thead>
<tr> <tr>
<th> Duration</th> <th> Duration</th>
@@ -208,25 +142,25 @@
</tbody> </tbody>
</table> </table>
</div> </li>
<div class="grid_3"> <li class="grid_2">
<form enctype="multipart/form-data" action="{{ formloc }}" method="post"> <form enctype="multipart/form-data" action="{{ formloc }}" method="post">
{{ form.value }} {{ form.pieceunit }} {{ form.value }} {{ form.pieceunit }}
{% csrf_token %} {% csrf_token %}
</div>
<div class="grid_1">
minutes minutes
</div>
<div class="grid_2 omega">
<input name="piece" class="button green" <input name="piece" class="button green"
action="" action=""
type="submit" value="Add"> type="submit" value="Add">
</form> </form>
</div> </li>
</div> </ul>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_analytics.html' %}
{% endblock %}
+32 -65
View File
@@ -1,83 +1,50 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}View Workout {% endblock %} {% block title %}View Workout {% endblock %}
{% block content %} {% block main %}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>
{{ interactiveplot |safe }} {{ interactiveplot |safe }}
<script>
// Set things up to resize the plot on a window resize. You can play with
// the arguments of resize_width_height() to change the plot's behavior.
var plot_resize_setup = function () {
var plotid = Object.keys(Bokeh.index)[0]; // assume we have just one plot
var plot = Bokeh.index[plotid];
var plotresizer = function() {
// arguments: use width, use height, maintain aspect ratio
plot.resize_width_height(true, false, false);
};
window.addEventListener('resize', plotresizer);
plotresizer();
};
window.addEventListener('load', plot_resize_setup);
</script>
<style>
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
html, body {height: 100%; margin:5px;}
</style>
<div id="workouts" class="grid_12 alpha"> <h1>Interactive Plot</h1>
<ul class="main-content">
<h1>Interactive Plot</h1> <li class="grid_4">
{% if user.is_authenticated and mayedit %}
<div class="grid_2 alpha">
<p>
<a class="button gray small" href="/rowers/workout/{{ workout.id }}/edit">Edit Workout</a>
</p>
</div>
<div class="grid_2">
<p>
<a class="button gray small" href="/rowers/workout/{{ workout.id }}/advanced">Advanced Edit</a>
</p>
</div>
<div class="grid_2">
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/wind">Edit Wind Data</a>
</div>
<div class="grid_2">
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/stream">Edit Stream Data</a>
</div>
<div class="grid_2">
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/otwsetpower">OTW Power</a>
</div>
{% endif %}
</div>
<div id="theplot" class="grid_12 alpha flexplot">
{{ the_div|safe }} {{ the_div|safe }}
</div> </li>
<li class="grid_4">
<div class="grid_12"> <p>
<p> <h2>Notes</h2>
<h3>Notes</h3>
<ul> <ul>
<li>Is your erg pace slower than you expected? This may be a sign of room for improvement regarding your technique. An alternative explanation is that your team mates are fatter than they told you! For example, put 80.0 kg if your four consists of 2 70kg guys and 2 90kg guys.</li> <li>
<li>In order to speed up the calculation, we are running the calculation only for every 10th datapoint, using interpolation in between. Some very fine pace shifts may disappear.</li> Is your erg pace slower than you expected? This may be a sign of room for improvement regarding your technique. An alternative explanation is that your team mates are fatter than they told you! For example, put 80.0 kg if your four consists of 2 70kg guys and 2 90kg guys.
<li>While the wind and stream correction is fairly reliable, the OTW to OTE conversion sometimes throws errors. Those data points are omitted and replaced by interpolated values. We are sorry if this messed up some of your plots.</li> </li>
<li>Read more details about the way we calculate things <a href="/rowers/physics"</a>here</a>.</li> <li>
In order to speed up the calculation, we are running the calculation only for every 10th datapoint, using interpolation in between. Some very fine pace shifts may disappear.
</li>
<li>
While the wind and stream correction is fairly reliable, the OTW to OTE conversion sometimes throws errors. Those data points are omitted and replaced by interpolated values. We are sorry if this messed up some of your plots.
</li>
<li>
Read more details about the way we calculate things <a href="/rowers/physics">here</a>.
</li>
</ul> </ul>
</p> </p>
</li>
</div> </ul>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_workout.html' %}
{% endblock %}
+36 -101
View File
@@ -1,4 +1,4 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
@@ -8,77 +8,28 @@
{% block title %}Workouts{% endblock %} {% block title %}Workouts{% endblock %}
{% block content %} {% block main %}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>
{{ interactiveplot |safe }} {{ interactiveplot |safe }}
<script>
// Set things up to resize the plot on a window resize. You can play with
// the arguments of resize_width_height() to change the plot's behavior.
var plot_resize_setup = function () {
var plotid = Object.keys(Bokeh.index)[0]; // assume we have just one plot
var plot = Bokeh.index[plotid];
var plotresizer = function() {
// arguments: use width, use height, maintain aspect ratio
plot.resize_width_height(true, true, false);
};
window.addEventListener('resize', plotresizer);
plotresizer();
};
window.addEventListener('load', plot_resize_setup);
</script>
<style>
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
html, body {height: 100%; margin:5px;}
</style>
<div id="title" class="grid_12 alpha"> {% if theuser %}
<div class="grid_10 alpha"> <h1>{{ theuser.first_name }}'s Ranking Pieces</h1>
{% if theuser %} {% else %}
<h3>{{ theuser.first_name }}'s Ranking Pieces</h3> <h1>{{ user.first_name }}'s Ranking Pieces</h1>
{% else %} {% endif %}
<h3>{{ user.first_name }}'s Ranking Pieces</h3>
{% endif %}
</div>
<div class="grid_2 omega">
{% if user.is_authenticated and user|is_manager %}
<div class="grid_2 alpha dropdown">
<button class="grid_2 alpha button green small dropbtn">
{{ theuser.first_name }} {{ theuser.last_name }}
</button>
<div class="dropdown-content">
{% for member in user|team_members %}
{% if workouttype == 'water' %}
<a class="button green small" href="/rowers/{{ member.id }}/otw-bests/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}">{{ member.first_name }} {{ member.last_name }}</a>
{% else %}
<a class="button green small" href="/rowers/{{ member.id }}/ote-ranking/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}">{{ member.first_name }} {{ member.last_name }}</a>
{% endif %}
{% endfor %}
</div>
{% else %}
&nbsp;
{% endif %}
</div>
</div>
<div id="summary" class="grid_6 alpha"> <ul class="main-content">
<li class="grid_2">
<p>Summary for {{ theuser.first_name }} {{ theuser.last_name }} <p>Summary for {{ theuser.first_name }} {{ theuser.last_name }}
between {{ startdate|date }} and {{ enddate|date }}</p> between {{ startdate|date }} and {{ enddate|date }}</p>
<p>Direct link for other users:
{% if workouttype == 'water' %}
<a href="/rowers/{{ id }}/otw-bests/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}">https://rowsandall.com/rowers/{{ id }}/otw-bests/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}</a>
{% else %}
<a href="/rowers/{{ id }}/ote-ranking/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}">https://rowsandall.com/rowers/{{ id }}/ote-ranking/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}</a>
{% endif %}
</p>
<p>The table gives the efforts you marked as Ranking Piece. <p>The table gives the efforts you marked as Ranking Piece.
The graph shows the best segments from those pieces, plotted as The graph shows the best segments from those pieces, plotted as
average power (over the segment) vs the duration of the segment/ average power (over the segment) vs the duration of the segment/
@@ -88,52 +39,38 @@
<p>When you change the date range, the algorithm calculates new <p>When you change the date range, the algorithm calculates new
parameters in a background process. You may have to reload the parameters in a background process. You may have to reload the
page to get an updated prediction.</p> page to get an updated prediction.</p>
<p>At the bottom of the page, you will find predictions derived from the model.</p> <p>At the bottom of the page, you will find predictions derived from the model.</p>
</div> </li>
<div id="form" class="grid_6 omega"> <li class="grid_2">
<p>Use this form to select a different date range:</p> <p>Use this form to select a different date range:</p>
<p> <p>
Select start and end date for a date range: Select start and end date for a date range:
<div class="grid_4 alpha">
<form enctype="multipart/form-data" action="" method="post"> <form enctype="multipart/form-data" action="" method="post">
<table> <table>
{{ dateform.as_table }} {{ dateform.as_table }}
</table> </table>
{% csrf_token %} {% csrf_token %}
</div> <input name='daterange' class="button green" type="submit" value="Submit">
<div class="grid_2 omega">
<input name='daterange' class="button green" type="submit" value="Submit"> </form>
</div>
<div class="grid_4 alpha">
<form enctype="multipart/form-data" action="" method="post">
Or use the last {{ deltaform }} days.
</div>
<div class="grid_2 omega">
{% csrf_token %}
<input name='datedelta' class="button green" type="submit" value="Submit">
</form> </form>
</div> </li>
</div>
<li class="grid_4">
<div id="theplot" class="grid_12 alpha"> <h2>Critical Power Plot</h2>
<h2>Critical Power Plot</h2>
{{ the_div|safe }} {{ the_div|safe }}
</div> </li>
<div class="grid_12 alpha"> <li class="grid_2">
<h2>Ranking Piece Results</h2> <h2>Ranking Piece Results</h2>
{% if rankingworkouts %} {% if rankingworkouts %}
<table width="70%" class="listtable"> <table width="100%" class="listtable">
<thead> <thead>
<tr> <tr>
<th> Distance</th> <th> Distance</th>
@@ -166,17 +103,16 @@
<p> No ranking workouts found </p> <p> No ranking workouts found </p>
{% endif %} {% endif %}
</div> </li>
<div id="predictions" class="grid_12 alpha"> <li class="grid_2">
<h2>Pace predictions for Ranking Pieces</h2> <h2>Pace predictions for Ranking Pieces</h2>
<p>Add non-ranking piece using the form. The piece will be added in the prediction tables below. </p> <p>Add non-ranking piece using the form. The piece will be added in the prediction tables below. </p>
<div id="cpmodel" class="grid_6 alpha"> <table width="100%" class="listtable">
<table width="70%" class="listtable">
<thead> <thead>
<tr> <tr>
<th> Duration</th> <th> Duration</th>
@@ -200,25 +136,24 @@
</tbody> </tbody>
</table> </table>
</div> </li>
<div class="grid_3"> <li class="grid_2">
<form enctype="multipart/form-data" action="{{ formloc }}" method="post"> <form enctype="multipart/form-data" action="{{ formloc }}" method="post">
{{ form.value }} {{ form.pieceunit }} {{ form.value }} {{ form.pieceunit }}
{% csrf_token %} {% csrf_token %}
</div>
<div class="grid_1">
minutes minutes
</div>
<div class="grid_2 omega">
<input name="piece" class="button green" <input name="piece" class="button green"
action="" action=""
type="submit" value="Add"> type="submit" value="Add">
</form> </form>
</div> </li>
</ul>
</div> {% endblock %}
{% block sidebar %}
{% include 'menu_analytics.html' %}
{% endblock %} {% endblock %}
+32 -33
View File
@@ -1,32 +1,14 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}Advanced Features {% endblock %} {% block title %}Advanced Features {% endblock %}
{% block content %} {% block main %}
<div id="workouts" class="grid_6 alpha">
<h1>Run OTW Power Calculations</h1>
<h1>Run OTW Power Calculations</h1> <ul class="main-content">
<div class="grid_2 alpha"> <li class="grid_4">
<p>
<a class="button gray small" href="/rowers/workout/{{ workout.id }}/edit">Edit Workout</a>
</p>
</div>
<div class="grid_2">
<p>
<a class="button gray small" href="/rowers/workout/{{ workout.id }}/workflow">Workflow View</a>
</p>
</div>
<div class="grid_2 omega">
<p>
<a class="button gray small" href="/rowers/workout/{{ workout.id }}/advanced">Advanced Edit</a>
</p>
</div>
<div class="grid_6 alpha">
<p> <p>
For the advanced OTW power and wind correction calculation, For the advanced OTW power and wind correction calculation,
we need to know the boat type and the average weight per crew member. we need to know the boat type and the average weight per crew member.
@@ -39,6 +21,22 @@
at the cost of a slight reduction in accuracy. It is recommended at the cost of a slight reduction in accuracy. It is recommended
to keep this option selected.</p> to keep this option selected.</p>
<p>
The power calculations take wind and stream as inputs.
</p>
<p>
<a href="/rowers/workout/{{ workout.id }}/wind">Set wind strength and direction</a>
</p>
<p>
<a href="/rowers/workout/{{ workout.id }}/stream">
Set river stream strength
</a>
</p>
</li>
<li class="grid_2">
<form enctype="multipart/form-data" action="{{ formloc }}" method="post"> <form enctype="multipart/form-data" action="{{ formloc }}" method="post">
{% if form.errors %} {% if form.errors %}
<p style="color: red;"> <p style="color: red;">
@@ -50,26 +48,27 @@
{{ form.as_table }} {{ form.as_table }}
</table> </table>
{% csrf_token %} {% csrf_token %}
</div> <div id="formbutton" class="tooltip">
<div id="formbutton" class="grid_2 prefix_2 suffix_2 tooltip">
<p><input class="button green" type="submit" value="Update & Run"></p> <p><input class="button green" type="submit" value="Update & Run"></p>
<span class="tooltiptext">Start the calculations to get power values for your row.</span> <span class="tooltiptext">Start the calculations to get power values for your row.</span>
</div> </div>
</form> </form>
</li>
</div> <li class="grid_2">
<div id="advancedplots" class="grid_6 omega">
<div> <div>
<img src="/static/img/rivercurrent.jpg" width="400"> <img src="/static/img/rivercurrent.jpg" width="400">
</div> </div>
<div> <div>
The Rowsandall Physics Department at work. The Rowsandall Physics Department at work.
</div> </div>
</div> </li>
</ul>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_workout.html' %}
{% endblock %}
+8 -10
View File
@@ -1,11 +1,12 @@
{% load rowerfilters %} {% load rowerfilters %}
{% load tz %} {% load tz %}
<div class="grid_6 suffix_3 alpha"> <ul class="main-content">
<li class="grid_2">
<table width=100%> <table width=100%>
<tr> <tr>
{% localtime on %} {% localtime on %}
<th>Date/Time:</th><td>{{ workout.startdatetime|localtime}}</td> <th>Date/Time:</th><td>{{ workout.startdatetime|localtime}}</td>
{% endlocaltime %} {% endlocaltime %}
</tr><tr> </tr><tr>
<th>Distance:</th><td>{{ workout.distance }}m</td> <th>Distance:</th><td>{{ workout.distance }}m</td>
</tr><tr> </tr><tr>
@@ -21,11 +22,8 @@
<a href="/rowers/workout/{{ workout.id }}/comment">Comment ({{ aantalcomments }})</a> <a href="/rowers/workout/{{ workout.id }}/comment">Comment ({{ aantalcomments }})</a>
</td> </td>
</tr><tr>
<th>Public link to interactive chart</th>
<td>
<a href="/rowers/workout/{{ workout.id }}/interactiveplot">https://rowsandall.com/rowers/workout/{{ workout.id }}/interactiveplot</a>
<td>
</tr> </tr>
</table> </table>
</div> </li>
</ul>
+6 -2
View File
@@ -1,9 +1,13 @@
<div style="height:100%;" id="theplot" class="grid_9 alpha flexplot"> <ul class="main-content">
<li class="grid_2">
<div class="mapdiv">
{{ mapdiv|safe }} {{ mapdiv|safe }}
{{ mapscript|safe }} {{ mapscript|safe }}
</div> </div>
</li>
</ul>
+5 -6
View File
@@ -1,14 +1,13 @@
<div class="grid_9"> <p>
<div class="grid_1 alpha">
<div class="fb-share-button" data-href="https://rowsandall.com/rowers/workout/{{ workout.id }}" data-layout="button" data-size="small" data-mobile-iframe="false"> <div class="fb-share-button" data-href="https://rowsandall.com/rowers/workout/{{ workout.id }}" data-layout="button" data-size="small" data-mobile-iframe="false">
<a class="fb-xfbml-parse-ignore" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=https://rowsandall.com/rowers/workout/{{ workout.id }}">Share</a> <a class="fb-xfbml-parse-ignore" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=https://rowsandall.com/rowers/workout/{{ workout.id }}">Share</a>
</div>
</div> </div>
<div class="grid_1 suffix_7 omega"> </p>
<a class="twitter-share-button" <p>
<a class="twitter-share-button"
href="https://twitter.com/intent/tweet" href="https://twitter.com/intent/tweet"
data-url="https://rowsandall.com/rowers/workout/{{ workout.id }}" data-url="https://rowsandall.com/rowers/workout/{{ workout.id }}"
data-text="@rowsandall #rowingdata">Tweet</a> data-text="@rowsandall #rowingdata">Tweet</a>
</div> </p>
+4 -2
View File
@@ -1,6 +1,7 @@
{% load rowerfilters %} {% load rowerfilters %}
{% load tz %} {% load tz %}
<div class="grid_6 suffix_3 alpha"> <ul class="main-content">
<li>
<table width=100%> <table width=100%>
<tr> <tr>
<th>Comments</th> <th>Comments</th>
@@ -10,4 +11,5 @@
</tr> </tr>
</table> </table>
</div> </li>
</ul>
+9 -6
View File
@@ -1,11 +1,14 @@
{% if statcharts %} {% if statcharts %}
<h2>Static Charts</h2> <h2>Static Charts</h2>
{% for graph in statcharts %} <ul class="main-content">
<div id="thumb-container" class="grid_3 alpha"> {% for graph in statcharts %}
<li>
<a href="/rowers/graph/{{ graph.id }}/"> <a href="/rowers/graph/{{ graph.id }}/">
<img src="/{{ graph.filename }}" <img src="/{{ graph.filename }}"
onerror="this.src='/static/img/rowingtimer.gif'" onerror="this.src='/static/img/rowingtimer.gif'"
alt="{{ graph.filename }}" width="180" height="150"></a> alt="{{ graph.filename }}" width="180" height="150">
</div> </a>
{% endfor %} </li>
{% endif %} {% endfor %}
{% endif %}
</ul>
+2 -4
View File
@@ -1,5 +1,3 @@
<div class="grid_2 alpha"> <p>
<p>
<a class="button gray small" href="/rowers/workout/{{ workout.id }}/stats">Workout Stats</a> <a class="button gray small" href="/rowers/workout/{{ workout.id }}/stats">Workout Stats</a>
</p> </p>
</div>
+123 -125
View File
@@ -1,166 +1,164 @@
{% extends "newbase.html" %}
{% block title %}About us{% endblock title %}
{% block main %}
{% extends "base.html" %} <h1>How we calculate things</h1>
{% block title %}About us{% endblock title %}
{% block content %}
<div class="grid_6 alpha"> <ul class="main-content">
<h3>How we calculate things</h3> <li class="grid_2">
<p>You are reading this because you want to understand how the wind/stream conversion and the conversion from OTW pace to OTE pace works.</p> <p>You are reading this because you want to understand how the wind/stream conversion and the conversion from OTW pace to OTE pace works.</p>
<p>The conversions are done using a one-dimensional mechanical model that is <p>The conversions are done using a one-dimensional mechanical model that is
introduced <a href="https://sanderroosendaal.wordpress.com/index/">here</a>. introduced <a href="https://sanderroosendaal.wordpress.com/index/">here</a>.
The model takes into account, among others, the following parameters: The model takes into account, among others, the following parameters:
<ul> <ul>
<li>Stroke rate</li> <li>Stroke rate</li>
<li>Stroke length</li> <li>Stroke length</li>
<li>Rigging parameters</li> <li>Rigging parameters</li>
<li>Rower and boat weight</li> <li>Rower and boat weight</li>
</ul> </ul>
For this site, we use "standard" rigging parameters, blade shapes, and FISA minimum boat weights. For the eight, I add the weight of a cox (at the FISA minimum weight). The stroke length is also set at a fixed value, but in the future I For this site, we use "standard" rigging parameters, blade shapes, and FISA minimum boat weights. For the eight, I add the weight of a cox (at the FISA minimum weight). The stroke length is also set at a fixed value, but in the future I
will allow you to adjust to your own stroke length. will allow you to adjust to your own stroke length.
</p> </p>
<p> <p>
Knowing boat type (rigging), pace and stroke rate, and taking into account Knowing boat type (rigging), pace and stroke rate, and taking into account
the influence of wind and stream (if provided), I am able to find the the influence of wind and stream (if provided), I am able to find the
mechanical power that you provide to the rowing system by a reverse mechanical power that you provide to the rowing system by a reverse
calculation. That is, I vary the input force until I find the one that calculation. That is, I vary the input force until I find the one that
corresponds to your actual pace at that stroke rate. corresponds to your actual pace at that stroke rate.
</p> </p>
<p> <p>
Knowing the power, I can calculate how fast you would have gone without Knowing the power, I can calculate how fast you would have gone without
external wind and stream influences by running the calculation in a forward external wind and stream influences by running the calculation in a forward
way, using the power and force profile found. This is the wind/stream way, using the power and force profile found. This is the wind/stream
corrected pace, which I think is useful to know and be able to compare corrected pace, which I think is useful to know and be able to compare
from training to training and between different rowing venues. from training to training and between different rowing venues.
</p> </p>
<p> <p>
Using another algorithm to calculate total mechanical power on an erg, I can Using another algorithm to calculate total mechanical power on an erg, I can
calculate what the erg display would show you if you rowed on the erg with calculate what the erg display would show you if you rowed on the erg with
the same average power, at the same stroke rate. The calculations are done the same average power, at the same stroke rate. The calculations are done
for a statical Concept2 erg with a fairly standard drag factor. I cannot for a statical Concept2 erg with a fairly standard drag factor. I cannot
take into account the fact that you may use different technique or would take into account the fact that you may use different technique or would
row at a different stroke rate on the erg. row at a different stroke rate on the erg.
</p> </p>
<p> <p>
It is important to understand that the Power display on the erg is not showing It is important to understand that the Power display on the erg is not showing
you the complete picture. In my calculations, I use my proprietary algorithms you the complete picture. In my calculations, I use my proprietary algorithms
to calculate the additional power that goes into moving your body weight up to calculate the additional power that goes into moving your body weight up
and down the slide on a static erg. To get the most accurate results, it is and down the slide on a static erg. To get the most accurate results, it is
important to be honest about your weight and set it independently for each important to be honest about your weight and set it independently for each
workout. workout.
</p> </p>
<p>Not taken into account are the following factors: <p>Not taken into account are the following factors:
<ul> <ul>
<li>Water Temperature</li> <li>Water Temperature</li>
<li>Heavier/shorter/wider boats than the ones used by the elite</li> <li>Heavier/shorter/wider boats than the ones used by the elite</li>
<li>Bungees, weed, or other artefacts slowing down the boat</li> <li>Bungees, weed, or other artefacts slowing down the boat</li>
<li>Boat stopping technique flaws</li> <li>Boat stopping technique flaws</li>
<li>Effect of wave height or cross-wind</li> <li>Effect of wave height or cross-wind</li>
</ul> </ul>
The water temperature has a small but measurable effect on the water density The water temperature has a small but measurable effect on the water density
(and thus on the drag). I am using the value at 20 degrees C, which is a (and thus on the drag). I am using the value at 20 degrees C, which is a
good average over the OTW season for a lake in a temperate climate. All good average over the OTW season for a lake in a temperate climate. All
the other elements result in an equivalent erg pace that is probably slower the other elements result in an equivalent erg pace that is probably slower
than what you can achieve on the erg. So look at it as an incentive to than what you can achieve on the erg. So look at it as an incentive to
improve your technique (big effect) and/or buy a faster boat (minor effect). improve your technique (big effect) and/or buy a faster boat (minor effect).
If your OTW to OTE pace conversion results in numbers close to what you If your OTW to OTE pace conversion results in numbers close to what you
normally achieve on the erg, you are rowing like an elite rower (but possibly normally achieve on the erg, you are rowing like an elite rower (but possibly
at a lower power)! When I get around it, I will try to model the effect of cross-wind. at a lower power)! When I get around it, I will try to model the effect of cross-wind.
</p> </p>
<p> <p>
I have checked the model both from a Physics perspective (I have a degree in I have checked the model both from a Physics perspective (I have a degree in
Physics, if you are interested) and compared with the data available. Physics, if you are interested) and compared with the data available.
An important data set has been published <a href="http://www.biorow.com/RBN_en_2007_files/App2007RowBiomNews08.pdf">here</a> by Dr Kleshnev. For sculling, An important data set has been published <a href="http://www.biorow.com/RBN_en_2007_files/App2007RowBiomNews08.pdf">here</a> by Dr Kleshnev. For sculling,
my algorithms are extremely close in reproducing that data set. For sweep my algorithms are extremely close in reproducing that data set. For sweep
rowing, I am still fine tuning some parameters, but I am close for a pair and rowing, I am still fine tuning some parameters, but I am close for a pair and
a four. I had to make assumptions about Kleshnev's data, especially about the a four. I had to make assumptions about Kleshnev's data, especially about the
stroke rate, but as I got realistic stroke rates (35 and higher) for world stroke rate, but as I got realistic stroke rates (35 and higher) for world
record performance, I am quite confident. record performance, I am quite confident.
</p> </p>
<p> <p>
On top of that I am constantly comparing the model's results to my own sculling On top of that I am constantly comparing the model's results to my own sculling
and rowing, and I will be the first to admit flaws and correct them. So please and rowing, and I will be the first to admit flaws and correct them. So please
contact me if there are any inconsistencies, suspicions, questions or simply contact me if there are any inconsistencies, suspicions, questions or simply
if you want to chat about Rowing Physics. if you want to chat about Rowing Physics.
</p> </p>
</li>
<li class="grid_2">
<h2>Manual</h2>
</div> <p>Here's the best way - in my mind - to use the Rowing Physics
<div class="grid_6 omega"> functionality. I am assuming you have successfully uploaded or imported
<h3>Manual</h3> a rowing workout. You must have position data (lat/long) with your row. A
TCX from CrewNerd or RiM or a workout imported from SportTracks or Strava
(where you see a map of your workout on those sites) should have those
data. I am working on adding the FIT file format that is used by SpeedCoach
GPS. For now, export the data to Strava and then import them here.
</p>
<p>Here's the best way - in my mind - to use the Rowing Physics <p>Recipe for success:
functionality. I am assuming you have successfully uploaded or imported <ol>
a rowing workout. You must have position data (lat/long) with your row. A
TCX from CrewNerd or RiM or a workout imported from SportTracks or Strava
(where you see a map of your workout on those sites) should have those
data. I am working on adding the FIT file format that is used by SpeedCoach
GPS. For now, export the data to Strava and then import them here.
</p>
<p>Recipe for success:
<ol>
<li>Click on the workout. This will bring you to the workout Edit view</li> <li>Click on the workout. This will bring you to the workout Edit view</li>
<li>Click on the "Advanced" button</li> <li>Look for three menu items labelled "Edit Wind Data", "Edit Stream
<li>Click on "Geeky Stuff"</li>
<li>Look for three buttons labelled "Edit Wind Data", "Edit Stream
Data" and "OTW Power"</li> Data" and "OTW Power"</li>
<li>If you have wind or stream data, click on the appropriate <li>If you have wind or stream data, click on the appropriate
button and enter your data.</li> menu item and enter your data.</li>
<li>If you have both wind and stream, click the shortcut button
on the respective page to take you to the other parameter</li>
<li>Click on OTW Power</li> <li>Click on OTW Power</li>
<li>Select the boat type and enter the average weight <li>Select the boat type and enter the average weight
per crew member. per crew member.
Do not use the crew total weight.</li> Do not use the crew total weight.</li>
<li>Click "Update & Run"</li> <li>Click "Update & Run"</li>
<li>Go do something else. You will receive an email when the calculations are finished. The calculation itself will take about 10 minutes for an <li>Go do something else. You will receive an email when the calculations are finished. The calculation itself will take about 10 minutes for an
hour long row, but there may be other people's calculations in the queue, so hour long row, but there may be other people's calculations in the queue, so
it may take longer.</li> it may take longer.</li>
<li>Progress can be monitored by clicking on "here" in the message <li>Progress can be monitored by clicking on "here" in the message
at the top of the page advising that the calculation has at the top of the page advising that the calculation has
begun.</li> begun.</li>
<li> </ol>
When the calculation is complete, go back to the "Geeky Stuff" page </p>
and click on "Corrected Pace Plot" to see the result. From here, you can re-run the calculation with different parameters.</li>
</ol>
</p>
<p> <p>
Once you have run the calculation, the boat type, average crew weight, Once you have run the calculation, the boat type, average crew weight,
Power and corrected pace data are stored permanently on the site. If you would Power and corrected pace data are stored permanently on the site. If you would
export the data to Strava or SportTracks now, those sites will have the export the data to Strava or SportTracks now, those sites will have the
Power data. Power data.
</p> </p>
<h3>Why does the calculation take so much time?</h3> <h2>Why does the calculation take so much time?</h2>
<p>I am running the calculations from a first principles base, so for <p>I am running the calculations from a first principles base, so for
each data point that I am calculating, I am finding the stroke average each data point that I am calculating, I am finding the stroke average
force, then calculating corrected pace (wind/stream) and finding the force, then calculating corrected pace (wind/stream) and finding the
corresponding erg power. I am not taking any shortcuts. The advantage corresponding erg power. I am not taking any shortcuts. The advantage
of this approach is that I can give you numbers irrespective of your of this approach is that I can give you numbers irrespective of your
weight, speed, stroke rate, sex, etc. The model can deal with circumstances weight, speed, stroke rate, sex, etc. The model can deal with circumstances
it has not encountered before. The downside is that it takes time.</p> it has not encountered before. The downside is that it takes time.</p>
<p> <p>
A much faster approach would be to simply take pre-calculated data from A much faster approach would be to simply take pre-calculated data from
a table and interpolate. The advantage of this approach is is speed. The a table and interpolate. The advantage of this approach is is speed. The
disadvantage is that extrapolation outside the limits of the available disadvantage is that extrapolation outside the limits of the available
data is dangerous and will lead to erroneous results.</p> data is dangerous and will lead to erroneous results.</p>
<p>Future versions of this site will use a hybrid approach <p>Future versions of this site will use a hybrid approach
but only for pace/wind/stream/stroke rate/weight combinations that I consider but only for pace/wind/stream/stroke rate/weight combinations that I consider
well validated. For that, I need to collect data, so keep the workouts coming! well validated. For that, I need to collect data, so keep the workouts coming!
</p> </p>
<img src="/static/img/validation.png" width="450"> <img src="/static/img/validation.png" width="450">
</div> </li>
</ul>
{% endblock content %} {% endblock %}
{% block sidebar %}
{% include 'menu_help.html' %}
{% endblock %}
@@ -1,66 +1,14 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}Plan entire microcycle{% endblock %} {% block title %}Plan entire microcycle{% endblock %}
{% block content %} {% block main %}
<div class="grid_12 alpha"> <h1>Create Sessions for {{ rower.user.first_name }} {{ rower.user.last_name }}</h1>
{% include "planningbuttons.html" %}
</div>
<div class="grid_12 alpha"> <ul class="main-content">
<div id="left" class="grid_6 alpha"> <li class="grid_4">
<h1>Create Sessions for {{ rower.user.first_name }} {{ rower.user.last_name }}</h1>
</div>
<div id="timeperiod" class="grid_2 dropdown">
<button class="grid_2 alpha button gray small dropbtn">Select Time Period ({{ timeperiod|verbosetimeperiod }})</button>
<div class="dropdown-content">
<a class="button gray small alpha"
href="/rowers/sessions/multicreate/today/rower/{{ rower.id }}">
Today
</a>
<a class="button gray small alpha"
href="/rowers/sessions/multicreate/thisweek/rower/{{ rower.id }}">
This Week
</a>
<a class="button gray small alpha"
href="/rowers/sessions/multicreate/thismonth/rower/{{ rower.id }}">
This Month
</a>
<a class="button gray small alpha"
href="/rowers/sessions/multicreate/lastweek/rower/{{ rower.id }}">
Last Week
</a>
<a class="button gray small alpha"
href="/rowers/sessions/multicreate/lastmonth/rower/{{ rower.id }}">
Last Month
</a>
<a class="button gray small alpha"
href="/rowers/sessions/multicreate/nextweek/rower/{{ rower.id }}">
Next Week
</a>
<a class="button gray small alpha"
href="/rowers/sessions/multicreate/nextmonth/rower/{{ rower.id }}">
Next Month
</a>
</div>
</div>
{% if user.is_authenticated and user|is_manager %}
<div class="grid_2 dropdown">
<button class="grid_2 alpha button green small dropbtn">
{{ rower.user.first_name }} {{ rower.user.last_name }}
</button>
<div class="dropdown-content">
{% for member in user|team_rowers %}
<a class="button green small" href="/rowers/sessions/multicreate/{{ timeperiod }}/rower/{{ member.id }}">{{ member.user.first_name }} {{ member.user.last_name }}</a>
{% endfor %}
</div>
</div>
{% endif %}
</div>
<div class="grid_12 alpha">
<p> <p>
On this page, you can create and edit sessions for an entire time On this page, you can create and edit sessions for an entire time
period. You see a list of the current sessions planned for the period. You see a list of the current sessions planned for the
@@ -100,19 +48,18 @@
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
<a class="button gray small grid_2 alpha" href="/rowers/sessions/multicreate/{{ timeperiod }}/rower/{{ rower.id }}/extra/{{ extrasessions }}">Add More</a> <a href="/rowers/sessions/multicreate/user/{{ rower.user.id }}/extra/{{ extrasessions }}/?when={{ timeperiod }}">
<button class="button green small grid_2" type="submit">Submit</button> Add More
<a class="button blue small grid_2" href="/rowers/sessions/multiclone/{{ timeperiod }}/rower/{{ rower.id }}">Clone multiple sessions</a> </a>
or
<a href="/rowers/sessions/multiclone/user/{{ rower.user.id }}/?when={{ timeperiod }}">
Clone multiple sessions
</a>
<button class="button green small" type="submit">Submit</button>
</form> </form>
</li>
</ul>
<div class="grid_6 prefix_6" id="id_guidance">
</div>
</div>
{% endblock %}
{% block scripts %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="/static/js/jquery.formset.js"></script> <script src="/static/js/jquery.formset.js"></script>
@@ -200,3 +147,7 @@
</script> </script>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_plan.html' %}
{% endblock %}
+16 -75
View File
@@ -1,71 +1,14 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}New Planned Session{% endblock %} {% block title %}New Planned Session{% endblock %}
{% block content %} {% block main %}
<div class="grid_12 alpha"> <h1>Create Sessions for {{ rower.user.first_name }} {{ rower.user.last_name }}</h1>
{% include "planningbuttons.html" %}
</div>
<div class="grid_12 alpha"> <ul class="main-content">
<div id="left" class="grid_6 alpha"> <li class="grid_2">
<h1>Create Sessions for {{ rower.user.first_name }} {{ rower.user.last_name }}</h1>
</div>
<div id="timeperiod" class="grid_2 dropdown">
<button class="grid_2 alpha button gray small dropbtn">Select Time Period ({{ timeperiod|verbosetimeperiod }})</button>
<div class="dropdown-content">
<a class="button gray small alpha"
href="/rowers/sessions/create/today/rower/{{ rower.id }}">
Today
</a>
<a class="button gray small alpha"
href="/rowers/sessions/create/thisweek/rower/{{ rower.id }}">
This Week
</a>
<a class="button gray small alpha"
href="/rowers/sessions/create/thismonth/rower/{{ rower.id }}">
This Month
</a>
<a class="button gray small alpha"
href="/rowers/sessions/create/lastweek/rower/{{ rower.id }}">
Last Week
</a>
<a class="button gray small alpha"
href="/rowers/sessions/create/lastmonth/rower/{{ rower.id }}">
Last Month
</a>
<a class="button gray small alpha"
href="/rowers/sessions/create/nextweek/rower/{{ rower.id }}">
Next Week
</a>
<a class="button gray small alpha"
href="/rowers/sessions/create/nextmonth/rower/{{ rower.id }}">
Next Month
</a>
</div>
</div>
{% if user.is_authenticated and user|is_manager %}
<div class="grid_2 dropdown">
<button class="grid_2 alpha button green small dropbtn">
{{ rower.user.first_name }} {{ rower.user.last_name }}
</button>
<div class="dropdown-content">
{% for member in user|team_rowers %}
<a class="button green small" href="/rowers/sessions/create/{{ timeperiod }}/rower/{{ member.id }}">{{ member.user.first_name }} {{ member.user.last_name }}</a>
{% endfor %}
</div>
</div>
{% endif %}
<div class="grid_2 omega">
<a class="button small gray" href="/rowers/list-courses">Courses</a>
</div>
</div>
<div class="grid_12 alpha">
<div id="right" class="grid_6 alpha">
<h1>Plan</h1> <h1>Plan</h1>
<p> <p>
Click on session name to view Click on session name to view
@@ -100,10 +43,10 @@
<td> {{ ps.sessionvalue }} </td> <td> {{ ps.sessionvalue }} </td>
<td> {{ ps.sessionunit }} </td> <td> {{ ps.sessionunit }} </td>
<td> <td>
<a class="small" href="/rowers/sessions/{{ ps.id }}/edit/{{ timeperiod }}/rower/{{ rower.id }}">Edit</a> <a class="small" href="/rowers/sessions/{{ ps.id }}/edit/user/{{ rower.user.id }}/?when={{ timeperiod }}">Edit</a>
</td> </td>
<td> <td>
<a class="small" href="/rowers/sessions/{{ ps.id }}/clone/{{ timeperiod }}/rower/{{ rower.id }}">Clone</a> <a class="small" href="/rowers/sessions/{{ ps.id }}/clone/user/{{ rower.user.id }}/?when={{ timeperiod }}">Clone</a>
</td> </td>
<td> <td>
@@ -113,11 +56,8 @@
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
</div> </li>
<li class="grid_2">
<div class="grid_6 omega">
<h1>New Session</h1> <h1>New Session</h1>
<form enctype="multipart/form-data" action="{{ formloc }}" method="post"> <form enctype="multipart/form-data" action="{{ formloc }}" method="post">
{% if form.errors %} {% if form.errors %}
@@ -130,15 +70,12 @@
{{ form.as_table }} {{ form.as_table }}
</table> </table>
{% csrf_token %} {% csrf_token %}
<div id="formbutton" class="grid_1 prefix_4 suffix_1">
<input class="button green" type="submit" value="Save"> <input class="button green" type="submit" value="Save">
</div>
</form> </form>
</div> <div class="padded" id="id_guidance">
</div> </li>
<div class="grid_6 prefix_6" id="id_guidance"> </ul>
</div>
{% endblock %} {% endblock %}
{% block scripts %} {% block scripts %}
@@ -240,3 +177,7 @@
</script> </script>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_plan.html' %}
{% endblock %}
@@ -1,32 +1,25 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% block title %}Planned Session{% endblock %} {% block title %}Planned Session{% endblock %}
{% block content %} {% block main %}
<div class="grid_12 alpha"> <h1>Confirm Delete</h1>
{% include "planningbuttons.html" %} <p>This will permanently delete the planned session</p>
</div> <ul class="main-content">
<div id="left" class="grid_6 alpha"> <li class="grid_2">
<h1>Confirm Delete</h1>
<p>This will permanently delete the planned session</p>
<div class="grid_2 alpha">
<p> <p>
<a class="button green small" href="/rowers/sessions/">Cancel</a> <form action="" method="post">
</div> {% csrf_token %}
<p>Are you sure you want to delete <em>{{ object }}</em>?</p>
<div class="grid_2"> <input class="button red" type="submit" value="Confirm">
<p> </form>
<a class="button red small" href="/rowers/sessions/{{ ps.id }}/delete">Delete</a>
</p> </p>
</div> </li>
</div> <li class="grid_2">
<div id="right" class="grid_6 omega"> <h2>Session {{ psdict.name.1 }}</h2>
<h1>Session {{ psdict.name.1 }}</h1>
<table class="listtable shortpadded"> <table class="listtable shortpadded">
{% for attr in attrs %} {% for attr in attrs %}
{% for key,value in psdict.items %} {% for key,value in psdict.items %}
@@ -38,8 +31,13 @@
{% endfor %} {% endfor %}
{% endfor %} {% endfor %}
</table> </table>
</div> </li>
</ul>
{% endblock %}
{% block sidebar %}
{% include 'menu_plan.html' %}
{% endblock %} {% endblock %}
+32 -75
View File
@@ -1,65 +1,21 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}Update Planned Session{% endblock %} {% block title %}Update Planned Session{% endblock %}
{% block content %} {% block main %}
<div class="grid_12 alpha"> <h1>Edit Session</h1>
{% include "planningbuttons.html" %}
</div>
<div class="grid_12 alpha">
<div id="left" class="grid_6 alpha">
<h1>Edit Session</h1>
</div>
<div id="timeperiod" class="grid_2 dropdown">
<button class="grid_2 alpha button gray small dropbtn">Select Time Period ({{ timeperiod|verbosetimeperiod }})</button>
<div class="dropdown-content">
<a class="button gray small alpha"
href="/rowers/sessions/create/today/rower/{{ rower.id }}">
Today
</a>
<a class="button gray small alpha"
href="/rowers/sessions/create/thisweek/rower/{{ rower.id }}">
This Week
</a>
<a class="button gray small alpha"
href="/rowers/sessions/create/thismonth/rower/{{ rower.id }}">
This Month
</a>
<a class="button gray small alpha"
href="/rowers/sessions/create/lastweek/rower/{{ rower.id }}">
Last Week
</a>
<a class="button gray small alpha"
href="/rowers/sessions/create/lastmonth/rower/{{ rower.id }}">
Last Month
</a>
<a class="button gray small alpha"
href="/rowers/sessions/create/nextweek/rower/{{ rower.id }}">
Next Week
</a>
<a class="button gray small alpha"
href="/rowers/sessions/create/nextmonth/rower/{{ rower.id }}">
Next Month
</a>
</div>
</div>
{% if user.is_authenticated and user|is_manager %} {% if user.is_authenticated and user|is_manager %}
<div class="grid_2"> <p>
<a class="button green small alpha" href="/rowers/sessions/teamedit/{{ thesession.id }}/{{ timeperiod}}"> <a href="/rowers/sessions/teamedit/{{ thesession.id }}/">
Assign to my Teams Assign to my Teams
</a> </a>
</div> </p>
{% endif %} {% endif %}
<div class="grid_2 omega"> <ul class="main-content">
<a class="button small gray" href="/rowers/list-courses">Courses</a> <li class="grid_2">
</div> <h2>Plan</h2>
</div>
<div class="grid_12 alpha">
<div id="right" class="grid_6 alpha">
<h1>Plan</h1>
<p> <p>
Click on session name to view Click on session name to view
</p> </p>
@@ -93,11 +49,11 @@
<td> {{ ps.sessionvalue }} </td> <td> {{ ps.sessionvalue }} </td>
<td> {{ ps.sessionunit }} </td> <td> {{ ps.sessionunit }} </td>
<td> <td>
<a class="small" href="/rowers/sessions/{{ ps.id }}/edit/{{ timeperiod }}/rower/{{ rower.id }}">Edit</a> <a class="small" href="/rowers/sessions/{{ ps.id }}/edit/user/{{ rower.user.id }}">Edit</a>
</td> </td>
<td> <td>
<a class="small" <a class="small"
href="/rowers/sessions/{{ ps.id }}/clone/{{ timeperiod }}/rower/{{ rower.id }}">Clone</a> href="/rowers/sessions/{{ ps.id }}/clone/user/{{ rower.user.id }}">Clone</a>
</td> </td>
<td> <td>
<a class="small" href="/rowers/sessions/{{ ps.id }}/deleteconfirm">Delete</a> <a class="small" href="/rowers/sessions/{{ ps.id }}/deleteconfirm">Delete</a>
@@ -106,41 +62,42 @@
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
</div> </li>
<li class="grid_2">
<div class="grid_6 omega"> <h2>{{ thesession.name }}</h2>
<h1>{{ thesession.name }}</h1>
<form enctype="multipart/form-data" action="{{ formloc }}" method="post"> <form enctype="multipart/form-data" action="{{ formloc }}" method="post">
{% if form.errors %} {% if form.errors %}
<p style="color: red;"> <p style="color: red;">
Please correct the error{{ form.errors|pluralize }} below. Please correct the error{{ form.errors|pluralize }} below.
</p> </p>
{% endif %} {% endif %}
<p>
<table> <table>
{{ form.as_table }} {{ form.as_table }}
</table> </table>
</p>
{% csrf_token %} {% csrf_token %}
<div class="grid_1 prefix_2 alpha"> <div id="id_guidance">
<a class="red button small" href="/rowers/sessions/{{ thesession.id }}/deleteconfirm">Delete</a>
</div>
<div class="grid_1">
<a class="gray button small" href="/rowers/sessions/{{ thesession.id }}/clone">Clone</a>
</div>
<div id="formbutton" class="grid_1 suffix_1 omega">
<input class="button green" action="/rowers/sessions/{{ thesession.id }}/edit/{{ timeperiod }}/rower/{{ rower.id }}" type="submit" value="Save">
</div>
<div class="grid_6" id="id_guidance">
</div> </div>
<p>
</div> <a href="/rowers/sessions/{{ thesession.id }}/deleteconfirm">Delete</a>
<a href="/rowers/sessions/{{ thesession.id }}/clone/?when={{ timeperiod }}">Clone</a>
</p>
<input class="button green"
action="/rowers/sessions/{{ thesession.id }}/edit/user/{{ rower.user.id }}" type="submit" value="Save">
</form> </form>
</div>
</li>
</ul>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_plan.html' %}
{% endblock %}
{% block scripts %} {% block scripts %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script> <script>
+60 -100
View File
@@ -1,85 +1,33 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}Planned Sessions{% endblock %} {% block title %}Planned Sessions{% endblock %}
{% block content %} {% block main %}
<div class="grid_12 alpha">
{% include "planningbuttons.html" %} <h1>Planned Sessions for {{ rower.user.first_name }} {{ rower.user.last_name }}</h1>
</div>
<div class="grid_6 alpha"> {% if plannedsessions %}
<h1>Plan for {{ rower.user.first_name }} {{ rower.user.last_name }}</h1> <p>
</div>
<div id="timeperiod" class="grid_2 dropdown">
<button class="grid_2 alpha button gray small dropbtn">Select Time Period ({{ timeperiod|verbosetimeperiod }})</button>
<div class="dropdown-content">
<a class="button gray small alpha"
href="/rowers/sessions/today/rower/{{ rower.id }}">
Today
</a>
<a class="button gray small alpha"
href="/rowers/sessions/thisweek/rower/{{ rower.id }}">
This Week
</a>
<a class="button gray small alpha"
href="/rowers/sessions/thismonth/rower/{{ rower.id }}">
This Month
</a>
<a class="button gray small alpha"
href="/rowers/sessions/lastweek/rower/{{ rower.id }}">
Last Week
</a>
<a class="button gray small alpha"
href="/rowers/sessions/lastmonth/rower/{{ rower.id }}">
Last Month
</a>
<a class="button gray small alpha"
href="/rowers/sessions/nextweek/rower/{{ rower.id }}">
Next Week
</a>
<a class="button gray small alpha"
href="/rowers/sessions/nextmonth/rower/{{ rower.id }}">
Next Month
</a>
</div>
</div>
{% if user.is_authenticated and user|is_manager %}
<div class="grid_2 dropdown">
<button class="grid_2 alpha button green small dropbtn">
{{ rower.user.first_name }} {{ rower.user.last_name }}
</button>
<div class="dropdown-content">
{% for member in user|team_rowers %}
<a class="button green small" href="/rowers/sessions/{{ timeperiod }}/rower/{{ member.id }}">{{ member.user.first_name }} {{ member.user.last_name }}</a>
{% endfor %}
</div>
</div>
{% endif %}
<div class="grid_2 omega">
<a class="button small gray" href="/rowers/list-courses">Courses</a>
</div>
<div class="grid_12 alpha">
{% if plannedsessions %}
<p>
Click on session name to view, edit to change the session and on the Click on session name to view, edit to change the session and on the
traffic light symbol to add workouts to the session traffic light symbol to add workouts to the session
</p> </p>
<table width="90%" class="listtable shortpadded"> <table width="90%" class="listtable shortpadded">
<thead> <thead>
<tr> <tr>
<th>Status</th> <th align="left">Status</th>
<th>On or After</th> <th align="left">On or After</th>
<th>On or Before</th> <th align="left">On or Before</th>
<th>Name</th> <th align="left">Name</th>
<th>Type</th> <th align="left">Type</th>
<th>Mode</th> <th align="left">Mode</th>
<th>Edit</th> <th align="left">Edit</th>
<th>Planned</th> <th align="left">Planned</th>
<th>Actual</th> <th align="left">Actual</th>
<th>&nbsp;</th> <th align="left">&nbsp;</th>
<th>Completion Date</th> <th align="left">Completion Date</th>
<th> <th align="left">
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -88,25 +36,30 @@
<td> <td>
{% if completeness|lookup:ps.id == 'not done' %} {% if completeness|lookup:ps.id == 'not done' %}
{% if ps.sessiontype != 'race' %} {% if ps.sessiontype != 'race' %}
<a class="white dot" href="/rowers/sessions/manage/{{ timeperiod }}/rower/{{ rower.id }}/session/{{ ps.id }}">&nbsp;</a> <a class="white dot"
href="/rowers/sessions/manage/session/{{ ps.id }}/user/{{ rower.user.id }}/?when={{ timeperiod }}">
&nbsp;</a>
{% else %} {% else %}
<a class="white dot" href="/rowers/virtualevent/{{ ps.id }}/submit">&nbsp;</a> <a class="white dot" href="/rowers/virtualevent/{{ ps.id }}/submit">&nbsp;</a>
{% endif %} {% endif %}
{% elif completeness|lookup:ps.id == 'completed' %} {% elif completeness|lookup:ps.id == 'completed' %}
{% if ps.sessiontype != 'race' %} {% if ps.sessiontype != 'race' %}
<a class="green dot" href="/rowers/sessions/manage/{{ timeperiod }}/rower/{{ rower.id }}/session/{{ ps.id }}">&nbsp;</a> <a class="green dot"
href="/rowers/sessions/manage/session/{{ ps.id }}/user/{{ rower.user.id }}/?when={{ timeperiod }}">&nbsp;</a>
{% else %} {% else %}
<a class="green dot" href="/rowers/virtualevent/{{ ps.id }}/submit">&nbsp;</a> <a class="green dot" href="/rowers/virtualevent/{{ ps.id }}/submit">&nbsp;</a>
{% endif %} {% endif %}
{% elif completeness|lookup:ps.id == 'partial' %} {% elif completeness|lookup:ps.id == 'partial' %}
{% if ps.sessiontype != 'race' %} {% if ps.sessiontype != 'race' %}
<a class="orange dot" href="/rowers/sessions/manage/{{ timeperiod }}/rower/{{ rower.id }}/session/{{ ps.id }}">&nbsp;</a> <a class="orange dot"
href="/rowers/sessions/manage/session/{{ ps.id }}/user/{{ rower.user.id }}?when={{ timeperiod }}">&nbsp;</a>
{% else %} {% else %}
<a class="orange dot" href="/rowers/virtualevent/{{ ps.id }}/submit">&nbsp;</a> <a class="orange dot" href="/rowers/virtualevent/{{ ps.id }}/submit">&nbsp;</a>
{% endif %} {% endif %}
{% else %} {% else %}
{% if ps.sessiontype != 'race' %} {% if ps.sessiontype != 'race' %}
<a class="red dot" href="/rowers/sessions/manage/{{ timeperiod }}/rower/{{ rower.id }}/session/{{ ps.id }}">&nbsp;</a> <a class="red dot"
href="/rowers/sessions/manage/session/{{ ps.id }}/user/{{ rower.user.id }}?when={{ timeperiod }}">&nbsp;</a>
{% else %} {% else %}
<a class="red dot" href="/rowers/virtualevent/{{ ps.id }}/submit">&nbsp;</a> <a class="red dot" href="/rowers/virtualevent/{{ ps.id }}/submit">&nbsp;</a>
{% endif %} {% endif %}
@@ -118,10 +71,10 @@
{% if ps.sessiontype != 'race' %} {% if ps.sessiontype != 'race' %}
{% if ps.name != '' %} {% if ps.name != '' %}
<a class="small" <a class="small"
href="/rowers/sessions/{{ ps.id }}/{{ timeperiod }}/rower/{{ rower.id }}">{{ ps.name }}</a> href="/rowers/sessions/{{ ps.id }}/user/{{ rower.user.id }}">{{ ps.name }}</a>
{% else %} {% else %}
<a class="small" <a class="small"
href="/rowers/sessions/{{ ps.id }}/{{ timeperiod }}/rower/{{ rower.id }}">Unnamed Session</a> href="/rowers/sessions/{{ ps.id }}/user/{{ rower.user.id }}">Unnamed Session</a>
{% endif %} {% endif %}
{% else %} {% else %}
{% if ps.name != '' %} {% if ps.name != '' %}
@@ -138,7 +91,7 @@
<td> <td>
{% if ps.manager == request.user %} {% if ps.manager == request.user %}
<a class="small" <a class="small"
href="/rowers/sessions/{{ ps.id }}/edit/{{ timeperiod }}/rower/{{ rower.id }} ">Edit</a> href="/rowers/sessions/{{ ps.id }}/edit/user/{{ rower.user.id }}/?when={{ timeperiod }}">Edit</a>
{% else %} {% else %}
&nbsp; &nbsp;
{% endif %} {% endif %}
@@ -154,28 +107,31 @@
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
{% else %} {% else %}
You have no planned workouts for this period. Planned workouts are created You have no planned workouts for this period. Planned workouts are created
by your coach if you are part of a team. You can create your own by your coach if you are part of a team. You can create your own
planned workouts by purchasing the "Coach" or "Self-Coach" plans. planned workouts by purchasing the "Coach" or "Self-Coach" plans.
{% endif %} {% endif %}
<p> <p>
<a class="grid_2 button gray" href="/rowers/sessions/print/{{ timeperiod }}/rower/{{ rower.id }}">Print View</a> <a class="grid_2 button gray"
<p> href="/rowers/sessions/print/user/{{ rower.user.id }}/?when={{ timeperiod }}">
{% if unmatchedworkouts %} Print View</a>
<h1>Workouts that are not linked to any session</h1> </p>
{% if unmatchedworkouts %}
<h2>Workouts that are not linked to any session</h2>
<p>
<table width="90%" class="listtable shortpadded"> <table width="90%" class="listtable shortpadded">
<thead> <thead>
<tr> <tr>
<th style="width:80"> Date</th> <th style="width:80"> Date</th>
<th> Time</th> <th align="left"> Time</th>
<th> Name</th> <th align="left"> Name</th>
<th> Type</th> <th align="left"> Type</th>
<th> Distance </th> <th align="left"> Distance </th>
<th> Duration </th> <th align="left"> Duration </th>
<th> Avg HR </th> <th align="left"> Avg HR </th>
<th> Max HR </th> <th align="left"> Max HR </th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -214,9 +170,13 @@
{% endif %} {% endif %}
</div> </p>
</form> {% endblock %}
{% block sidebar %}
{% include 'menu_plan.html' %}
{% endblock %} {% endblock %}
@@ -1,10 +1,10 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}Workouts{% endblock %} {% block title %}Workouts{% endblock %}
{% block content %} {% block main %}
<script> <script>
function toggle(source) { function toggle(source) {
@@ -64,90 +64,12 @@
</script> </script>
<h1>Clone Multiple Sessions for {{ rower.user.first_name }} {{ rower.user.last_name }}</h1>
<div class="grid_12 alpha">
{% include "planningbuttons.html" %}
</div>
<div class="grid_6 alpha">
<h1>Clone Multiple Sessions</h1>
</div>
<div id="timeperiod" class="grid_2 dropdown">
<button class="grid_2 alpha button gray small dropbtn">Select Time Period ({{ timeperiod|verbosetimeperiod }})</button>
<div class="dropdown-content">
<a class="button gray small alpha"
href="/rowers/sessions/multiclone/today">
Today
</a>
<a class="button gray small alpha"
href="/rowers/sessions/multiclone/thisweek">
This Week
</a>
<a class="button gray small alpha"
href="/rowers/sessions/multiclone/thismonth">
This Month
</a>
<a class="button gray small alpha"
href="/rowers/sessions/multiclone/lastweek">
Last Week
</a>
<a class="button gray small alpha"
href="/rowers/sessions/multiclone/lastmonth">
Last Month
</a>
<a class="button gray small alpha"
href="/rowers/sessions/multiclone/nextweek">
Next Week
</a>
<a class="button gray small alpha"
href="/rowers/sessions/multiclone/nextmonth">
Next Month
</a>
</div>
</div>
{% if user.is_authenticated and user|is_manager %}
<div class="grid_2 dropdown">
<button class="grid_2 alpha button green small dropbtn">
Select Rower
</button>
<div class="dropdown-content">
{% for member in user|team_rowers %}
<a class="button green small" href="/rowers/sessions/multiclone/{{ timeperiod }}/rower/{{ member.id }}">{{ member.user.first_name }} {{ member.user.last_name }}</a>
{% endfor %}
</div>
</div>
<div class="grid_12 alpha">
<div class="grid_6 alpha">
<form enctype="multipart/form-data" method="post">
{% endif %}
<div class="grid_4 alpha">
<table>
{{ dateform.as_table }}
</table>
{% csrf_token %}
</div>
<div class="grid_2 omega">
<input name='daterange' class="button green" type="submit" value="Submit">
</div>
</form>
</div>
<div class="grid_5 prefix_1 omega">
<form id="searchform" method="get" accept-charset="utf-8">
<div class="grid_3 prefix_1 alpha">
<input class="searchfield" id="searchbox" name="q" type="text" placeholder="Search">
</div>
<div class="grid_1 omega">
<button class="button blue small" type="submit">
Search
</button>
</div>
</form>
</div>
</div>
<form enctype="multipart/form-data" method="post"> <form enctype="multipart/form-data" method="post">
<div id="workouts_table" class="grid_8 alpha"> <ul class="main-content">
<li class="grid_2">
{% if plannedsessions %} {% if plannedsessions %}
@@ -158,11 +80,11 @@
{{ form.as_table }} {{ form.as_table }}
</table> </table>
{% else %} {% else %}
<p> No sessions found </p> <p> No sessions found </p>
{% endif %} {% endif %}
</div> </li>
<div id="form_settings" class="grid_4 alpha"> <li class="grid_2">
<p>Select one or more planned sessions on the left, <p>Select one or more planned sessions on the left,
select the date when the new cycle starts below select the date when the new cycle starts below
and press submit</p> and press submit</p>
@@ -170,17 +92,18 @@
<table> <table>
{{ dateshiftform.as_table }} {{ dateshiftform.as_table }}
</table> </table>
<div class="grid_1 prefix_2 suffix_1">
<p> <p>
<input name='workoutselectform' class="button green" type="submit" value="Submit"> <input name='workoutselectform' class="button green" type="submit" value="Submit">
</p> </p>
</div>
<div class="grid_4">
<p>You can use the date and search forms above to search through all <p>You can use the date and search forms above to search through all
sessions.</p> sessions.</p>
</div> </li>
</div> </ul>
</form> </form>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_plan.html' %}
{% endblock %}
+17 -70
View File
@@ -1,100 +1,47 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}Planned Sessions{% endblock %} {% block title %}Planned Sessions{% endblock %}
{% block content %} {% block main %}
<div class="grid_12 alpha"> <h1>Plan for {{ rower.user.first_name }} {{ rower.user.last_name }}</h1>
{% include "planningbuttons.html" %}
</div>
<div class="grid_6 alpha">
<h1>Plan for {{ rower.user.first_name }} {{ rower.user.last_name }}</h1>
<p>
From {{ startdate }} to {{ enddate }}
</p>
</div>
<div id="timeperiod" class="grid_2 dropdown">
<button class="grid_2 alpha button gray small dropbtn">Select Time Period ({{ timeperiod|verbosetimeperiod }})</button>
<div class="dropdown-content">
<a class="button gray small alpha"
href="/rowers/sessions/print/today/rower/{{ rower.id }}">
Today
</a>
<a class="button gray small alpha"
href="/rowers/sessions/print/thisweek/rower/{{ rower.id }}">
This Week
</a>
<a class="button gray small alpha"
href="/rowers/sessions/print/thismonth/rower/{{ rower.id }}">
This Month
</a>
<a class="button gray small alpha"
href="/rowers/sessions/print/lastweek/rower/{{ rower.id }}">
Last Week
</a>
<a class="button gray small alpha"
href="/rowers/sessions/print/lastmonth/rower/{{ rower.id }}">
Last Month
</a>
<a class="button gray small alpha"
href="/rowers/sessions/print/nextweek/rower/{{ rower.id }}">
Next Week
</a>
<a class="button gray small alpha"
href="/rowers/sessions/print/nextmonth/rower/{{ rower.id }}">
Next Month
</a>
</div>
</div>
{% if user.is_authenticated and user|is_manager %}
<div class="grid_2 dropdown">
<button class="grid_2 alpha button green small dropbtn">
{{ rower.user.first_name }} {{ rower.user.last_name }}
</button>
<div class="dropdown-content">
{% for member in user|team_rowers %}
<a class="button green small" href="/rowers/sessions/print/{{ timeperiod }}/rower/{{ member.id }}">{{ member.user.first_name }} {{ member.user.last_name }}</a>
{% endfor %}
</div>
</div>
{% endif %}
<div class="grid_2 omega">
<a class="button small gray" href="/rowers/list-courses">Courses</a>
</div>
{% for ps in plannedsessions %} {% for ps in plannedsessions %}
<div class="grid_12 alpha" style="page-break-before: always, page-break-inside: avoid"> <h2><a href="/rowers/sessions/{{ ps.id }}">Session {{ ps.name }}</a></h2>
<h1><a href="/rowers/sessions/{{ ps.id }}">Session {{ ps.name }}</a></h1>
<table class="listtable shortpadded" width="80%"> <table class="listtable shortpadded" width="80%">
<tr> <tr>
<th>On or after</th><td>{{ ps.startdate }}</td> <th align="left">On or after</th><td>{{ ps.startdate }}</td>
</tr> </tr>
<tr> <tr>
<th>On or before</th><td>{{ ps.enddate }}</td> <th align="left">On or before</th><td>{{ ps.enddate }}</td>
</tr> </tr>
<tr> <tr>
<th>Session Type</th><td>{{ ps.sessiontype }}</td> <th align="left">Session Type</th><td>{{ ps.sessiontype }}</td>
</tr> </tr>
<tr> <tr>
<th>Session Mode</th><td>{{ ps.sessionmode }}</td> <th align="left">Session Mode</th><td>{{ ps.sessionmode }}</td>
</tr> </tr>
<tr> <tr>
<th>Criteria</th><td>{{ ps.criterium }}</td> <th align="left">Criteria</th><td>{{ ps.criterium }}</td>
</tr> </tr>
<tr> <tr>
<th>Value</th><td>{{ ps.sessionvalue }}</td> <th align="left">Value</th><td>{{ ps.sessionvalue }}</td>
</tr> </tr>
<tr> <tr>
<th>Unit</th><td>{{ ps.sessionunit }}</td> <th align="left">Unit</th><td>{{ ps.sessionunit }}</td>
</tr> </tr>
<tr> <tr>
<th>Comment</th><td>{{ ps.comment|linebreaks }}</td> <th align="left">Comment</th><td>{{ ps.comment|linebreaks }}</td>
</tr> </tr>
</table> </table>
</div>
{% endfor %} {% endfor %}
{% endblock %}
{% block sidebar %}
{% include 'menu_plan.html' %}
{% endblock %} {% endblock %}
+21 -82
View File
@@ -1,88 +1,24 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}Planned Sessions{% endblock %} {% block title %}Planned Sessions{% endblock %}
{% block content %} {% block main %}
<div class="grid_12 alpha"> {% if theteam %}
{% include "planningbuttons.html" %} <h1>Coach Overview. Team {{ theteam.name }}</h1>
</div> {% else %}
<div class="grid_4 alpha"> <h1>Coach Overview</h1>
{% if theteam %}
<h1>Coach Overview. Team {{ theteam.name }}</h1>
{% else %}
<h1>Coach Overview</h1>
{% endif %}
</div>
<div id="timeperiod" class="grid_2 dropdown">
<button class="grid_2 alpha button gray small dropbtn">Select Time Period ({{ timeperiod|verbosetimeperiod }})</button>
<div class="dropdown-content">
<a class="button gray small alpha"
href="/rowers/sessions/coach/today">
Today
</a>
<a class="button gray small alpha"
href="/rowers/sessions/coach/thisweek">
This Week
</a>
<a class="button gray small alpha"
href="/rowers/sessions/coach/thismonth">
This Month
</a>
<a class="button gray small alpha"
href="/rowers/sessions/coach/lastweek">
Last Week
</a>
<a class="button gray small alpha"
href="/rowers/sessions/coach/lastmonth">
Last Month
</a>
<a class="button gray small alpha"
href="/rowers/sessions/coach/nextweek">
Next Week
</a>
<a class="button gray small alpha"
href="/rowers/sessions/coach/nextmonth">
Next Month
</a>
</div>
</div>
{% if user.is_authenticated and user|is_manager %}
<div class="grid_2 dropdown">
<button class="grid_2 alpha button green small dropbtn">
Select Rower Individual Plan
</button>
<div class="dropdown-content">
{% for member in user|team_rowers %}
<a class="button green small" href="/rowers/sessions/{{ timeperiod }}/rower/{{ member.id }}">{{ member.user.first_name }} {{ member.user.last_name }}</a>
{% endfor %}
</div>
</div>
<div class="grid_2 dropdown">
<button class="grid_2 alpha button green small dropbtn">
Select Team
</button>
<div class="dropdown-content">
<a class="button green small" href="/rowers/sessions/coach/{{ timeperiod }}">
All Teams
</a>
{% for team in myteams %}
<a class="button green small" href="/rowers/sessions/coach/{{ timeperiod }}/team/{{ team.id }}">{{ team.name }}</a>
{% endfor %}
</div>
</div>
{% endif %} {% endif %}
<div class="grid_12 alpha">
<table width="90%" class="listtable"> <table width="90%" class="listtable">
<thead> <thead>
<tr> <tr>
<th>On or after</th> <th align="left">On or after</th>
<th>On or before</th> <th align="left">On or before</th>
<th>Preferred date</th> <th align="left">Preferred date</th>
<th>Name</th> <th align="left">Name</th>
{% for r in rowers %} {% for r in rowers %}
<th class="rotate"><div><span> <th class="rotate"><div><span>
{{ r.user.first_name }} {{ r.user.last_name }} {{ r.user.first_name }} {{ r.user.last_name }}
@@ -133,11 +69,11 @@
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
{% if unmatchedworkouts %} {% if unmatchedworkouts %}
<h1>Workouts that are not linked to any session</h1> <h1>Workouts that are not linked to any session</h1>
<table width="90%" class="listtable shortpadded"> <table width="90%" class="listtable shortpadded">
<thead> <thead>
<tr> <tr>
<th> Rower</th> <th> Rower</th>
@@ -187,11 +123,14 @@
</table> </table>
{% endif %} {% endif %}
</div>
</form> </form>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_plan.html' %}
{% endblock %}
+28 -76
View File
@@ -1,4 +1,4 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
@@ -16,83 +16,30 @@
{% endblock %} {% endblock %}
{% block content %} {% block main %}
<div class="grid_12 alpha"> <h1>Manage Plan Execution for {{ rower.user.first_name }} {{ rower.user.last_name }}</h1>
{% include "planningbuttons.html" %}
</div>
<div class="grid_12 alpha">
<div class="grid_6 alpha">
<h1>Manage Plan Execution for {{ rower.user.first_name }} {{ rower.user.last_name }}</h1>
</div>
<div id="timeperiod" class="grid_2 dropdown"> <p>Select one session on the left, and one or more workouts on the right
<button class="grid_2 alpha button gray small dropbtn">Select Time Period ({{ timeperiod|verbosetimeperiod }})</button>
<div class="dropdown-content">
<a class="button gray small alpha"
href="/rowers/sessions/manage/today/rower/{{ rower.id }}">
Today
</a>
<a class="button gray small alpha"
href="/rowers/sessions/manage/thisweek/rower/{{ rower.id }}">
This Week
</a>
<a class="button gray small alpha"
href="/rowers/sessions/manage/thismonth/rower/{{ rower.id }}">
This Month
</a>
<a class="button gray small alpha"
href="/rowers/sessions/manage/lastweek/rower/{{ rower.id }}">
Last Week
</a>
<a class="button gray small alpha"
href="/rowers/sessions/manage/lastmonth/rower/{{ rower.id }}">
Last Month
</a>
<a class="button gray small alpha"
href="/rowers/sessions/manage/nextweek/rower/{{ rower.id }}">
Next Week
</a>
<a class="button gray small alpha"
href="/rowers/sessions/manage/nextmonth/rower/{{ rower.id }}">
Next Month
</a>
</div>
</div>
{% if user.is_authenticated and user|is_manager %}
<div class="grid_2 dropdown">
<button class="grid_2 alpha button green small dropbtn">
{{ rower.user.first_name }} {{ rower.user.last_name }}
</button>
<div class="dropdown-content">
{% for member in user|team_rowers %}
<a class="button green small" href="/rowers/sessions/manage/{{ timeperiod }}/rower/{{ member.id }}">{{ member.user.first_name }} {{ member.user.last_name }}</a>
{% endfor %}
</div>
</div>
{% endif %}
</div>
<div class="grid_12 alpha">
<p>Select one session on the left, and one or more workouts on the right
to match the workouts to the session. For tests and training sessions, to match the workouts to the session. For tests and training sessions,
the selected workouts must be done on the same date. For all sessions, the selected workouts must be done on the same date. For all sessions,
the workout dates must be between the start and end date for the the workout dates must be between the start and end date for the
session. session.
</p> </p>
<p> <p>
If you select a workout that has already been matched to another session, If you select a workout that has already been matched to another session,
it will change to match this session. it will change to match this session.
</p> </p>
<p> <p>
Workouts marked with a red check mark (<span style="color:red"><b>&#10004;</b></span>) Workouts marked with a red check mark (<span style="color:red"><b>&#10004;</b></span>)
are currently linked to one of your sessions. A workout can only be assigned to are currently linked to one of your sessions. A workout can only be assigned to
one session at a time. one session at a time.
</p> </p>
</div>
<form id="session_form" action="/rowers/sessions/manage/{{ timeperiod }}/rower/{{ rower.id }}" <form id="session_form" action="/rowers/sessions/manage/user/{{ rower.user.id }}/?when={{ timeperiod }}"
method="post"> method="post">
<div class="grid_12 alpha"> <ul class="main-content">
<div class="grid_6 alpha"> <li class="grid_2">
<p>Planned Sessions</p> <h2>Planned Sessions</h2>
<table width="100%"> <table width="100%">
<tr> <tr>
{% for field in ps_form.hidden_fields %} {% for field in ps_form.hidden_fields %}
@@ -103,9 +50,9 @@
{% endfor %} {% endfor %}
</tr> </tr>
</table> </table>
</div> </li>
<div class="grid_6 omega"> <li class="grid_2">
<p>Workouts</p> <h2>Workouts</h2>
<table width="100%"> <table width="100%">
<tr> <tr>
{% for field in w_form.hidden_fields %} {% for field in w_form.hidden_fields %}
@@ -118,17 +65,22 @@
{% endfor %} {% endfor %}
</tr> </tr>
</table> </table>
</div> </li>
</div> <li class="grid_2">
<div class="grid_2 prefix_2 suffix_8">
{% csrf_token %} {% csrf_token %}
<input class="button green" type="submit" value="Submit"> <input class="button green" type="submit" value="Submit">
</div> </li>
</ul>
</form> </form>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_plan.html' %}
{% endblock %}
{% block scripts %} {% block scripts %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script> <script>
@@ -144,12 +96,12 @@
function getURL() { function getURL() {
var url = window.location.pathname; var url = window.location.pathname;
var selectedsession = $("input:radio[name='plannedsession']:checked").val(); var selectedsession = $("input:radio[name='plannedsession']:checked").val();
if (url.indexOf("/session/") >= 0) { if (url.indexOf("/session/") >= 0) {
url = url.replace(/\/session\/\d+/g, "/session/"+selectedsession); url = url.replace(/\/session\/\d+/g, "/session/"+selectedsession);
} else { } else {
url += "/session/"+selectedsession url = url.replace("manage","manage/session/"+selectedsession);
}; };
url += '?when={{ timeperiod }}'
return url}; return url};
+18 -58
View File
@@ -1,63 +1,23 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}New Planned Session{% endblock %} {% block title %}New Planned Session{% endblock %}
{% block content %} {% block main %}
<div class="grid_12 alpha"> <h1>Create Team Session</h1>
{% include "planningbuttons.html" %}
</div>
<div class="grid_12 alpha"> <form enctype="multipart/form-data" action="" method="post">
<div id="left" class="grid_6 alpha">
<h1>Create Team Session</h1>
</div>
<div id="timeperiod" class="grid_2 dropdown">
<button class="grid_2 alpha button gray small dropbtn">Select Time Period ({{ timeperiod|verbosetimeperiod }})</button>
<div class="dropdown-content">
<a class="button gray small alpha"
href="/rowers/sessions/create/today/rower/{{ rower.id }}">
Today
</a>
<a class="button gray small alpha"
href="/rowers/sessions/create/thisweek/rower/{{ rower.id }}">
This Week
</a>
<a class="button gray small alpha"
href="/rowers/sessions/create/thismonth/rower/{{ rower.id }}">
This Month
</a>
<a class="button gray small alpha"
href="/rowers/sessions/create/lastweek/rower/{{ rower.id }}">
Last Week
</a>
<a class="button gray small alpha"
href="/rowers/sessions/create/lastmonth/rower/{{ rower.id }}">
Last Month
</a>
<a class="button gray small alpha"
href="/rowers/sessions/create/nextweek/rower/{{ rower.id }}">
Next Week
</a>
<a class="button gray small alpha"
href="/rowers/sessions/create/nextmonth/rower/{{ rower.id }}">
Next Month
</a>
</div>
</div>
</div>
<div class="grid_12 alpha">
<form enctype="multipart/form-data" action="{{ formloc }}" method="post">
{% if form.errors %} {% if form.errors %}
<p style="color: red;"> <p style="color: red;">
Please correct the error{{ form.errors|pluralize }} below. Please correct the error{{ form.errors|pluralize }} below.
</p> </p>
{% endif %} {% endif %}
<ul class="main-content">
<li class="grid_2">
{% csrf_token %} {% csrf_token %}
<div id="right" class="grid_6 alpha">
<h1>Select Team</h1> <h1>Select Team</h1>
<p> <p>
<table> <table>
@@ -111,24 +71,20 @@
</table> </table>
</p> </p>
{% endif %} {% endif %}
</div> </li>
<li class="grid_2">
<div class="grid_6 omega">
<h1>New Session</h1> <h1>New Session</h1>
<table> <table>
{{ form.as_table }} {{ form.as_table }}
</table> </table>
<div id="formbutton" class="grid_1 prefix_4 suffix_1">
<input class="button green" type="submit" value="Save"> <input class="button green" type="submit" value="Save">
</div> <div id="id_guidance" class="padded">
</form>
<div class="grid_6" id="id_guidance">
</div> </div>
</div> </li>
</div> </ul>
</form>
{% endblock %} {% endblock %}
{% block scripts %} {% block scripts %}
@@ -234,3 +190,7 @@
</script> </script>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_plan.html' %}
{% endblock %}
+24 -65
View File
@@ -1,55 +1,12 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}New Planned Session{% endblock %} {% block title %}New Planned Session{% endblock %}
{% block content %} {% block main %}
<div class="grid_12 alpha"> <h1>Edit Team Session</h1>
{% include "planningbuttons.html" %} <form enctype="multipart/form-data" action="" method="post">
</div>
<div class="grid_12 alpha">
<div id="left" class="grid_6 alpha">
<h1>Edit Team Session</h1>
</div>
<div id="timeperiod" class="grid_2 dropdown">
<button class="grid_2 alpha button gray small dropbtn">Select Time Period ({{ timeperiod|verbosetimeperiod }})</button>
<div class="dropdown-content">
<a class="button gray small alpha"
href="/rowers/sessions/create/today/rower/{{ rower.id }}">
Today
</a>
<a class="button gray small alpha"
href="/rowers/sessions/create/thisweek/rower/{{ rower.id }}">
This Week
</a>
<a class="button gray small alpha"
href="/rowers/sessions/create/thismonth/rower/{{ rower.id }}">
This Month
</a>
<a class="button gray small alpha"
href="/rowers/sessions/create/lastweek/rower/{{ rower.id }}">
Last Week
</a>
<a class="button gray small alpha"
href="/rowers/sessions/create/lastmonth/rower/{{ rower.id }}">
Last Month
</a>
<a class="button gray small alpha"
href="/rowers/sessions/create/nextweek/rower/{{ rower.id }}">
Next Week
</a>
<a class="button gray small alpha"
href="/rowers/sessions/create/nextmonth/rower/{{ rower.id }}">
Next Month
</a>
</div>
</div>
</div>
<div class="grid_12 alpha">
<form enctype="multipart/form-data" action="{{ formloc }}" method="post">
{% if form.errors %} {% if form.errors %}
<p style="color: red;"> <p style="color: red;">
Please correct the error{{ form.errors|pluralize }} below. Please correct the error{{ form.errors|pluralize }} below.
@@ -57,7 +14,8 @@
{% endif %} {% endif %}
{% csrf_token %} {% csrf_token %}
<div id="right" class="grid_6 alpha"> <ul class="main-content">
<li class="grid_2">
<h1>Select Team</h1> <h1>Select Team</h1>
<p> <p>
Selecting a team assigns this session to all members of the team. Selecting a team assigns this session to all members of the team.
@@ -121,31 +79,28 @@
</table> </table>
</p> </p>
{% endif %} {% endif %}
</div> </li>
<li class="grid_2">
<div class="grid_6 omega">
<h1>Session {{ plannedsession.name }}</h1> <h1>Session {{ plannedsession.name }}</h1>
<table> <table>
{{ form.as_table }} {{ form.as_table }}
</table> </table>
<div class="grid_1 prefix_2 alpha"> <p>
<a class="red button small" href="/rowers/sessions/{{ plannedsession.id }}/deleteconfirm">Delete</a> <a href="/rowers/sessions/{{ plannedsession.id }}/deleteconfirm">Delete</a>
</div> </p>
<div class="grid_1"> <p>
<a class="gray button small" href="/rowers/sessions/{{ plannedsession.id }}/clone">Clone</a> <a href="/rowers/sessions/{{ plannedsession.id }}/clone">Clone</a>
</div> </p>
<div id="formbutton" class="grid_1 suffix_1 omega"> <p>
<input class="button green" type="submit" value="Save"> <input class="button green" type="submit" value="Save">
</div> </p>
</form> <div id="id_guidance" class="padded">
<div class="grid_6" id="id_guidance">
</div> </div>
</div> </li>
</ul>
</div> </form>
{% endblock %} {% endblock %}
{% block scripts %} {% block scripts %}
@@ -258,3 +213,7 @@
</script> </script>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_plan.html' %}
{% endblock %}
+29 -42
View File
@@ -1,4 +1,4 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
@@ -7,32 +7,18 @@
{% block title %}Planned Session{% endblock %} {% block title %}Planned Session{% endblock %}
{% block content %} {% block main %}
<div class="grid_12 alpha"> {% if user.is_authenticated and psdict.id.1|is_session_manager:user %}
{% include "planningbuttons.html" %} <p>
<a href="/rowers/sessions/{{ psdict.id.1 }}/edit/user/{{ rower.user.id }}">
</div>
<div class="grid_12 alpha">
<div class="grid_2 alpha">
{% if user.is_authenticated and psdict.id.1|is_session_manager:user %}
<a class="button small gray" href="/rowers/sessions/{{ psdict.id.1 }}/edit/rower/{{ rower.id }}">
Edit Session</a> Edit Session</a>
{% else %} </p>
&nbsp; {% endif %}
{% endif %} <h1>Session {{ psdict.name.1 }}</h1>
</div>
<div class="grid_2"> <ul class="main-content">
{% if plannedsession.sessiontype == 'coursetest' %} <li class="grid_2">
<a class="button small gray" href="/rowers/list-courses">Courses</a>
{% else %}
&nbsp;
{% endif %}
</div>
</div>
<div class="grid_12 alpha">
<div id="left" class="grid_6 alpha">
<h1>Session {{ psdict.name.1 }}</h1>
<table class="listtable shortpadded" width="95%"> <table class="listtable shortpadded" width="95%">
{% for attr in attrs %} {% for attr in attrs %}
{% for key,value in psdict.items %} {% for key,value in psdict.items %}
@@ -48,10 +34,10 @@
{% endfor %} {% endfor %}
{% endfor %} {% endfor %}
</table> </table>
</div> </li>
<div id="right" class="grid_6 omega"> <li class="grid_2">
{% if plannedsession.sessiontype == 'test' or plannedsession.sessiontype == 'coursetest' %} {% if plannedsession.sessiontype == 'test' or plannedsession.sessiontype == 'coursetest' %}
<h1>Ranking</h1> <h2>Ranking</h2>
<table id="rankingtable" class="listtable shortpadded tablesorter" width="80%"> <table id="rankingtable" class="listtable shortpadded tablesorter" width="80%">
<thead> <thead>
<tr> <tr>
@@ -107,16 +93,14 @@
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
</div> </li>
</div> <li class="grid_2">
<div class="grid_12 alpha"> <h2>{{ rower.user.first_name }} {{ rower.user.last_name }}</h2>
<div id="left" class="grid_6 alpha">
<h1>{{ rower.user.first_name }} {{ rower.user.last_name }}</h1>
<p>Status: {{ status }}</p> <p>Status: {{ status }}</p>
<p>Percentage complete: {{ ratio }} </p> <p>Percentage complete: {{ ratio }} </p>
</div> </li>
<div id="right" class="grid_6 omega"> <li class="grid_2">
<h1>Stats</h1> <h2>Stats</h2>
<table class="listtable shortpadded" width="100%"> <table class="listtable shortpadded" width="100%">
<thead> <thead>
<tr> <tr>
@@ -143,22 +127,25 @@
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
</div> </li>
<div class="grid_12 alpha">
<div id="left" class="grid_6 alpha">
{% if coursescript %} {% if coursescript %}
<h1>Course</h1> <li class="grid_2">
<h2>Course</h2>
{{ coursediv|safe }} {{ coursediv|safe }}
{{ coursescript|safe }} {{ coursescript|safe }}
</li>
{% endif %} {% endif %}
</div>
</div> </ul>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_plan.html' %}
{% endblock %}
{% block scripts %} {% block scripts %}
<script type="text/javascript" src="/static/admin/js/jquery.min.js"></script> <script type="text/javascript" src="/static/admin/js/jquery.min.js"></script>
<script type="text/javascript" src="/static/admin/js/jquery.tablesorter.min.js"></script> <script type="text/javascript" src="/static/admin/js/jquery.tablesorter.min.js"></script>
+6 -2
View File
@@ -1,10 +1,10 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}Workouts{% endblock %} {% block title %}Workouts{% endblock %}
{% block content %} {% block main %}
<h1>New Workouts Imported From Polar Flow</h1> <h1>New Workouts Imported From Polar Flow</h1>
<p>Due to a limitation in Polar Flow's API, we can only access new workouts. We <p>Due to a limitation in Polar Flow's API, we can only access new workouts. We
@@ -47,3 +47,7 @@
<p> No new workouts found </p> <p> No new workouts found </p>
{% endif %} {% endif %}
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_workouts.html' %}
{% endblock %}
+99 -65
View File
@@ -1,25 +1,25 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% block title %}Rowsandall Pro Membership{% endblock title %} {% block title %}Rowsandall Pro Membership{% endblock title %}
{% block content %} {% block main %}
{% load rowerfilters %} {% load rowerfilters %}
<div class="grid_6 alpha"> <h1>Paid Membership Plans</h1>
<h2>Pro Membership</h2>
<p>Donations are welcome to keep this web site going. To help cover the hosting <ul class="main-content">
<li class="grid_2">
<p>Donations are welcome to keep this web site going. To help cover the hosting
costs, I have created several paid plans offering advanced functionality. costs, I have created several paid plans offering advanced functionality.
Once I process your Once I process your
donation, I will give you access to some <q>special</q> features on this donation, I will give you access to some <q>special</q> features on this
website. </p> website. </p>
<p>The following table gives an overview of the different plans. As we are <p>The following table gives an overview of the different plans. As we are
constantly developing new functionality, the table might be slightly outdated. Don't constantly developing new functionality, the table might be slightly outdated. Don't
hesitate to contact us. </p> hesitate to contact us. </p>
<p>The Pro membership is open for a free 14 day trial</p> <p>The Pro membership is open for a free 14 day trial</p>
<p>
<p>
<table class="listtable paddedtable" width="80%"> <table class="listtable paddedtable" width="80%">
<thead> <thead>
<tr> <tr>
@@ -111,14 +111,14 @@
<td>&#10004;</td> <td>&#10004;</td>
</tr> </tr>
<tr> <tr>
<td>Create and manage teams.</a> <td>Create and manage teams.</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&#10004;</td> <td>&#10004;</td>
</tr> </tr>
<tr> <tr>
<td>Manage your athlete's workouts</a> <td>Manage your athlete's workouts</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
<td>&nbsp;</td> <td>&nbsp;</td>
@@ -126,86 +126,120 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
</p> </p>
<h2>Coach and Self-Coach Membership</h2>
<p>The Coach plan functionality listed is available to the coach only. Individual athletes <p>The Coach plan functionality listed is available to the coach only. Individual athletes
can purchase upgrades to Pro membership. can purchase upgrades to "Pro" and "Self-Coach" plans.
</p> </p>
<p>Click on the PayPal button to pay for your Pro membership. Before you pay, please <a href="/rowers/register">register</a> for the free Basic membership and add your user name to the form.
Your payment will be valid for one year with automatic renewal which you can stop at any time. <p>Rowsandall.com's Training Planning functionality
You will be taken to the secure PayPal payment site. is part of the paid "Self-Coach" and "Coach" plans.</p>
</p>
</div> <p>On the "Self-Coach" plan, you can plan your own sessions.</p>
<p>On the "Coach" plan, you can establish teams, see workouts done by
athletes on your team, and plan individual and group sessions for your
athletes.
</p>
<p>If you would like to find a coach who helps you plan your training
through rowsandall.com, contact me throught the contact form.</p>
<div class="grid_6 omega">
{% if user.rower.rowerplan == 'basic' and user.rower.protrialexpires|date_dif == 1 %} {% if user.rower.rowerplan == 'basic' and user.rower.protrialexpires|date_dif == 1 %}
<h2>Free Trial</h2> <h2>Free Trial</h2>
<p> <p>
You qualify for a 14 day free trial. No credit card needed. You qualify for a 14 day free trial. No credit card needed.
Try out Pro or Self-Coach membership for two weeks. Click the button below to Try out Pro or Self-Coach membership for two weeks. Click the button below to
sign up for the trial. After your trial period expires, you will be sign up for the trial. After your trial period expires, you will be
automatically reset to the Basic plan, unless you upgrade to Pro. automatically reset to the Basic plan, unless you upgrade to Pro.
</p> </p>
<div class="grid_6"><p><a class="button green small" href="/rowers/starttrial">Yes, I want to try Pro membership for 14 days for free. No strings attached.</a></p></div> <p><a class="button green small" href="/rowers/starttrial">Yes, I want to try Pro membership for 14 days for free. No strings attached.</a></p>
<div class="grid_6">&nbsp;</div> <p><a class="button green small" href="/rowers/startplantrial">Yes, I want to try Self-Coach membership for 14 days for free. No strings attached.</a></p>
<div class="grid_6"><p><a class="button green small" href="/rowers/startplantrial">Yes, I want to try Self-Coach membership for 14 days for free. No strings attached.</a></p></div> {% endif %}
{% endif %} </li>
<li class="grid_2">
<p>Click on the PayPal button to pay for your Pro membership. Before you pay, please <a href="/rowers/register">register</a> for the free Basic membership and add your user name to the form.
Your payment will be valid for one year.
You will be taken to the secure PayPal payment site.
</p>
<h2>Recurring Payment</h2> <h2>Recurring Payment</h2>
<p>You need a Paypal account for this</p> <p>You need a Paypal account for this. This is plan will automatically renew each year.</p>
<p> <p>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top"> <form class="paypal" action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
<input type="hidden" name="cmd" value="_s-xclick"> <input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="hosted_button_id" value="964GLEXX3THAW"> <input type="hidden" name="hosted_button_id" value="964GLEXX3THAW">
<table> <table>
<tr><td><input type="hidden" name="on0" value="Plans">Plans</td></tr><tr><td><select name="os0"> <tr>
<td>
<input type="hidden" name="on0" value="Plans">Plans
</td>
</tr>
<tr>
<td>
<select name="os0">
<option value="Pro Membership">Pro Membership : €15.00 EUR - yearly</option> <option value="Pro Membership">Pro Membership : €15.00 EUR - yearly</option>
<option value="Self-Coach Membership">Self-Coach Membership : €65.00 EUR - yearly</option> <option value="Self-Coach Membership">Self-Coach Membership : €65.00 EUR - yearly</option>
<option value="Coach 4 athletes or less">Coach 4 athletes or less : €90.00 EUR - yearly</option> <option value="Coach 4 athletes or less">Coach 4 athletes or less : €90.00 EUR - yearly</option>
<option value="Coach 4-10 athletes">Coach 4-10 athletes : €200.00 EUR - yearly</option> <option value="Coach 4-10 athletes">Coach 4-10 athletes : €200.00 EUR - yearly</option>
<option value="Coach more than 10 athletes">Coach more than 10 athletes : €450.00 EUR - yearly</option> <option value="Coach more than 10 athletes">Coach more than 10 athletes : €450.00 EUR - yearly</option>
</select> </td></tr> </select>
<tr><td><input type="hidden" name="on1" value="Your User Name">Your User Name</td></tr><tr><td><input type="text" name="os1" maxlength="200"></td></tr> </td>
</table> </tr>
<input type="hidden" name="currency_code" value="EUR"> <tr>
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_subscribeCC_LG_global.gif" border="0" name="submit" alt="PayPal The safer, easier way to pay online!"> <td>
<img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1"> <input type="hidden" name="on1" value="Your User Name">Your User Name
</form> </td>
</p> </tr>
<tr>
<h2>One Year Subscription</h2> <td>
<input type="text" name="os1" maxlength="200">
</td>
</tr>
</table>
<input type="hidden" name="currency_code" value="EUR">
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_subscribeCC_LG_global.gif" border="0" name="submit" alt="PayPal The safer, easier way to pay online!">
<img class="paypalpix" alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1">
</form>
</p>
<h2>One Year Subscription</h2>
<p>Only a credit card needed. Will not automatically renew</p> <p>Only a credit card needed. Will not automatically renew</p>
<p> <p>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top"> <form class="paypal" action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top"
<input type="hidden" name="cmd" value="_s-xclick"> >
<input type="hidden" name="hosted_button_id" value="2YB32HQTF96QW"> <input type="hidden" name="cmd" value="_s-xclick">
<table> <input type="hidden" name="hosted_button_id" value="2YB32HQTF96QW">
<tr><td><input type="hidden" name="on0" value="Plans">Plans</td></tr><tr><td><select name="os0"> <table>
<tr><td><input type="hidden" name="on0" value="Plans">Plans</td></tr><tr><td><select name="os0">
<option value="Pro Membership">Pro Membership €20.00 EUR</option> <option value="Pro Membership">Pro Membership €20.00 EUR</option>
<option value="Self-Coach Membership">Self-Coach Membership €75.00 EUR</option> <option value="Self-Coach Membership">Self-Coach Membership €75.00 EUR</option>
<option value="Coach - 4 athletes or less">Coach - 4 athletes or less €120.00 EUR</option> <option value="Coach - 4 athletes or less">Coach - 4 athletes or less €120.00 EUR</option>
<option value="Coach - 4-10 athletes">Coach - 4-10 athletes €250.00 EUR</option> <option value="Coach - 4-10 athletes">Coach - 4-10 athletes €250.00 EUR</option>
<option value="Coach - more than 10 athletes">Coach - more than 10 athletes €500.00 EUR</option> <option value="Coach - more than 10 athletes">Coach - more than 10 athletes €500.00 EUR</option>
</select> </td></tr> </select> </td></tr>
<tr><td><input type="hidden" name="on1" value="Your User Name">Your User Name</td></tr><tr><td><input type="text" name="os1" maxlength="200"></td></tr> <tr><td><input type="hidden" name="on1" value="Your User Name">Your User Name</td></tr><tr><td><input type="text" name="os1" maxlength="200"></td></tr>
</table> </table>
<input type="hidden" name="currency_code" value="EUR"> <input type="hidden" name="currency_code" value="EUR">
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_buynowCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!"> <input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_buynowCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
<img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1"> <img class="paypalpix" alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1">
</form> </form>
</p> </p>
<h2>Payment Processing</h2>
<p>After you do the payment, we will manually change your membership to
<h2>Payment Processing</h2>
<p>After you do the payment, we will manually change your membership to
"Pro". Depending on our availability, this may take some time "Pro". Depending on our availability, this may take some time
(typically one working day). Don't hesitate to contact us (typically one working day). Don't hesitate to contact us
if you have any questions at this stage.</p> if you have any questions at this stage.</p>
<p>If, for any reason, you are not happy with your Pro membership, please let me know through the contact form. I will contact you as soon as possible to discuss how we can make things better.</p> <p>If, for any reason, you are not happy with your Pro membership, please let me know through the contact form. I will contact you as soon as possible to discuss how we can make things better.</p>
</div> </li>
</ul>
{% endblock content %} {% endblock %}
{% block sidebar %}
{% include 'menu_help.html' %}
{% endblock %}
+14 -13
View File
@@ -1,4 +1,4 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
@@ -16,17 +16,13 @@
{% endblock %} {% endblock %}
{% block content %} {% block main %}
<div class="grid_12 alpha"> <h1>Submit Your Result for {{ race.name }}</h1>
<div class="grid_6 alpha">
<h1>Submit Your Result for {{ race.name }}</h1>
</div>
</div> <ul class="main-content">
<li class="grid_4">
<form id="race_submit_form" <form id="race_submit_form"
method="post"> method="post">
<div class="grid_12 alpha">
<p>Select one of the following workouts that you rowed within the race window</p> <p>Select one of the following workouts that you rowed within the race window</p>
<table width="100%"> <table width="100%">
<tr> <tr>
@@ -41,11 +37,12 @@
{% endfor %} {% endfor %}
</tr> </tr>
</table> </table>
</div> <p>
<div class="grid_2 prefix_2 suffix_8">
{% csrf_token %} {% csrf_token %}
<input class="button green" type="submit" value="Submit"> <input class="button green" type="submit" value="Submit">
</div> </p>
</li>
</ul>
</form> </form>
@@ -53,3 +50,7 @@
{% block scripts %} {% block scripts %}
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_racing.html' %}
{% endblock %}
+93 -151
View File
@@ -1,4 +1,4 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
@@ -11,109 +11,49 @@
{% endblock %} {% endblock %}
{% block content %} {% block main %}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script> <script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
<script async="true" type="text/javascript"> <script async="true" type="text/javascript">
Bokeh.set_log_level("info"); Bokeh.set_log_level("info");
</script> </script>
{{ interactiveplot |safe }} {{ interactiveplot |safe }}
<script>
// Set things up to resize the plot on a window resize. You can play with
// the arguments of resize_width_height() to change the plot's behavior.
var plot_resize_setup = function () {
var plotid = Object.keys(Bokeh.index)[0]; // assume we have just one plot
var plot = Bokeh.index[plotid];
var plotresizer = function() {
// arguments: use width, use height, maintain aspect ratio
plot.resize_width_height(true, true, false);
};
window.addEventListener('resize', plotresizer);
plotresizer();
};
window.addEventListener('load', plot_resize_setup);
</script>
<style>
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
html, body {height: 100%; margin:5px;}
</style>
<div id="title" class="grid_12 alpha"> {% if theuser %}
<div class="grid_10 alpha"> <h1>{{ theuser.first_name }}'s Ranking Pieces</h1>
{% if theuser %} {% else %}
<h3>{{ theuser.first_name }}'s Ranking Pieces</h3> <h1>{{ user.first_name }}'s Ranking Pieces</h1>
{% else %} {% endif %}
<h3>{{ user.first_name }}'s Ranking Pieces</h3>
{% endif %}
</div>
<div class="grid_2 omega">
{% if user.is_authenticated and user|is_manager %}
<div class="grid_2 alpha dropdown">
<button class="grid_2 alpha button green small dropbtn">
{{ theuser.first_name }} {{ theuser.last_name }}
</button>
<div class="dropdown-content">
{% for member in user|team_members %}
<a class="button green small" href="/rowers/{{ member.id }}/ote-bests2/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}">{{ member.first_name }} {{ member.last_name }}</a>
{% endfor %}
</div>
{% else %}
&nbsp;
{% endif %}
</div>
</div>
<div id="summary" class="grid_6 alpha"> <ul class="main-content">
<p>Summary for {{ theuser.first_name }} {{ theuser.last_name }} <li class="grid_4">
between {{ startdate|date }} and {{ enddate|date }}</p>
<p>Direct link for other users: <h2>Critical Power Plot</h2>
<a href="/rowers/{{ id }}/ote-bests/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}">https://rowsandall.com/rowers/{{ id }}/ote-bests/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}</a>
{{ the_div|safe }}
{% if age %}
<p>The dashed lines are based on the
<a href="https://log.concept2.com/rankings">Concept2</a>
rankings for your age, gender
and weight category. World class means within 5% of
<a href="http://www.concept2.com/indoor-rowers/racing/records/world">
World Record</a> in terms
of power.
The percentile lines are estimates of where the percentiles
of the Concept2 rankings historically are for those of exactly
your age, gender and weight class.
</p> </p>
{% endif %}
<p>The table gives the best efforts achieved on the </li>
<a href="https://log.concept2.com/rankings">official Concept2 ranking pieces</a> in the selected date range. Also the percentile scores on the <li class="grid_4">
chart are based on the Concept2 rankings.</p> <h2>Ranking Piece Results</h2>
</div>
<div id="form" class="grid_6 omega">
<p>Use this form to select a different date range:</p>
<p>
Select start and end date for a date range:
<div class="grid_4 alpha">
<form enctype="multipart/form-data" action="" method="post">
<table>
{{ dateform.as_table }}
</table>
{% csrf_token %}
</div>
<div class="grid_2 omega">
<input name='daterange' class="button green" type="submit" value="Submit"> </form>
</div>
<div class="grid_4 alpha">
<form enctype="multipart/form-data" action="" method="post">
Or use the last {{ deltaform }} days.
</div>
<div class="grid_2 omega">
{% csrf_token %}
<input name='datedelta' class="button green" type="submit" value="Submit">
</form>
</div>
</div>
<div class="grid_12 alpha">
<h2>Ranking Piece Results</h2>
{% if rankingworkouts %} {% if rankingworkouts %}
<table width="70%" class="listtable"> <table width="100%" class="listtable">
<thead> <thead>
<tr> <tr>
<th> Distance</th> <th> Distance</th>
@@ -133,7 +73,10 @@
<td> {{ workout.averagehr }} </td> <td> {{ workout.averagehr }} </td>
<td> {{ workout.maxhr }} </td> <td> {{ workout.maxhr }} </td>
<td> <td>
<a href="/rowers/workout/{{ workout.id }}/edit">{{ workout.name }}</a> </td> <a href="/rowers/workout/{{ workout.id }}/edit">
{{ workout.name }}
</a>
</td>
</tr> </tr>
@@ -144,65 +87,43 @@
<p> No ranking workouts found </p> <p> No ranking workouts found </p>
{% endif %} {% endif %}
<p>Missing your best pieces? Upload stroke data of any Concept2 <p>Missing your best pieces? Upload stroke data of any Concept2
ranking piece and they will be automatically added to this page.</p> ranking piece and they will be automatically added to this page.</p>
<p> Don't have stroke data for official Concept2 ranking pieces? <p> Don't have stroke data for official Concept2 ranking pieces?
The <a href="/rowers/promembership">PRO membership</a> ranking piece functionality The <a href="/rowers/promembership">PRO membership</a> ranking piece functionality
allows you to include your best non ranking pieces and even use allows you to include your best non ranking pieces and even use
parts of workouts for improved calculation accuracy. parts of workouts for improved calculation accuracy.
</p> </p>
<p>Want to add race results but you don't have stroke data? <p>Want to add race results but you don't have stroke data?
<a href="/rowers/addmanual">Click here.</a></p> <a href="/rowers/addmanual">Click here.</a></p>
<p>Scroll down for the chart and pace predictions for ranking pieces.</p> <p>Scroll down for the chart and pace predictions for ranking pieces.</p>
</div> </li>
<div id="theplot" class="grid_12 alpha">
<h2>Critical Power Plot</h2> <li class="grid_2">
<h2>Pace predictions for Ranking Pieces</h2>
{{ the_div|safe }} <p>Add non-ranking piece using the form. The piece will be added in the prediction tables below. </p>
{% if age %}
<p>The dashed lines are based on the
<a href="https://log.concept2.com/rankings">Concept2</a>
rankings for your age, gender
and weight category. World class means within 5% of
<a href="http://www.concept2.com/indoor-rowers/racing/records/world">
World Record</a> in terms
of power.
The percentile lines are estimates of where the percentiles
of the Concept2 rankings historically are for those of exactly
your age, gender and weight class.
</p>
{% endif %}
</div>
<div id="predictions" class="grid_12 alpha">
<h2>Pace predictions for Ranking Pieces</h2>
<p>Add non-ranking piece using the form. The piece will be added in the prediction tables below. </p>
<div class="grid_4 alpha">
<form enctype="multipart/form-data" action="{{ formloc }}" method="post"> <form enctype="multipart/form-data" action="{{ formloc }}" method="post">
{{ form.value }} {{ form.pieceunit }} {{ form.value }} {{ form.pieceunit }}
{% csrf_token %} {% csrf_token %}
</div>
<div class="grid_2 suffix_6 omega">
<input name="piece" class="button green" <input name="piece" class="button green"
formaction="/rowers/{{ id }}/ote-bests/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}" formaction="/rowers/ote-bests/user/{{ id }}/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}"
type="submit" value="Add"> type="submit" value="Add">
</form> </form>
</div> </li>/
<div id="paul" class="grid_6 alpha"> <li class="grid_2">
<h3>Paul's Law</h3> <h2>Paul's Law</h2>
{% if nrdata >= 1 %} {% if nrdata >= 1 %}
<table width="70%" class="listtable"> <table width="70%" class="listtable">
<thead> <thead>
<tr> <tr>
@@ -234,14 +155,14 @@
</tbody> </tbody>
</table> </table>
{% else %} {% else %}
<p>Insufficient data to make predictions</p> <p>Insufficient data to make predictions</p>
{% endif %} {% endif %}
</div> </li>
<div id="cpmodel" class="grid_6 omega"> <li class="grid_2">
<h3>CP Model</h3> <h2>CP Model</h2>
{% if nrdata >= 4 %} {% if nrdata >= 4 %}
<table width="70%" class="listtable"> <table width="70%" class="listtable">
<thead> <thead>
<tr> <tr>
@@ -273,16 +194,15 @@
</tbody> </tbody>
</table> </table>
{% else %} {% else %}
<p>Insufficient data to make predictions</p> <p>Insufficient data to make predictions</p>
{% endif %} {% endif %}
</div> </li>
<div class="grid_6 alpha">
{% if age and sex != 'not specified' %} {% if age and sex != 'not specified' %}
<h1>World Records</h1> <li>
<table width = "70%" class="listtable"> <h2>World Records</h2>
<table width = "100%" class="listtable">
<tbody> <tbody>
<tr> <tr>
<td> <td>
@@ -377,12 +297,34 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
{% else %} </li>
If you fill in your birth date and gender, you will see World Records for {% endif %}
your age group and gender at this place. You can edit your settings <li class="grid_2">
<a href="/rowers/me/edit">here</a>. <p>Use this form to select a different date range:</p>
{% endif %} <p>
</div> Select start and end date for a date range:
</div>
<form enctype="multipart/form-data" action="" method="post">
<table>
{{ dateform.as_table }}
</table>
{% csrf_token %}
<input name='daterange' class="button green" type="submit" value="Submit">
</form>
</li>
<li class="grid_2">
<p>Summary for {{ theuser.first_name }} {{ theuser.last_name }}
between {{ startdate|date }} and {{ enddate|date }}</p>
<p>The table gives the best efforts achieved on the
<a href="https://log.concept2.com/rankings">official Concept2 ranking pieces</a> in the selected date range. Also the percentile scores on the
chart are based on the Concept2 rankings.</p>
</li>
</ul>
{% endblock %} {% endblock %}
{% block sidebar %}
{% include 'menu_analytics.html' %}
{% endblock %}
+24 -4
View File
@@ -4,10 +4,30 @@
{% block main %} {% block main %}
<h1>Main</h1> <h1>Main</h1>
<p>Vestibulum consectetur sit amet nisi ut consectetur. Praesent efficitur, nibh vitae fringilla scelerisque, est neque faucibus quam, in iaculis purus libero eget mauris. Curabitur et luctus sapien, ac gravida orci. Aliquam erat volutpat. In hac habitasse platea dictumst. Aenean commodo, arcu a commodo efficitur, libero dolor mollis turpis, non posuere orci leo eget enim. Curabitur sit amet elementum orci, pulvinar dignissim urna. Morbi id ex eu ex congue laoreet. Aenean tincidunt dolor justo, semper pretium libero luctus nec. Ut vulputate metus accumsan leo imperdiet tincidunt. Phasellus nec rutrum dolor. Cras imperdiet sollicitudin arcu, id interdum nibh <a href="">fermentum</a> in.
</p> <ul class="main-content">
<p>Vestibulum consectetur sit amet nisi ut consectetur. Praesent efficitur, nibh vitae fringilla scelerisque, est neque faucibus quam, in iaculis purus libero eget mauris. Curabitur et luctus sapien, ac gravida orci. Aliquam erat volutpat. In hac habitasse platea dictumst. Aenean commodo, arcu a commodo efficitur, libero dolor mollis turpis, non posuere orci leo eget enim. Curabitur sit amet elementum orci, pulvinar dignissim urna. Morbi id ex eu ex congue laoreet. Aenean tincidunt dolor justo, semper pretium libero luctus nec. Ut vulputate metus accumsan leo imperdiet tincidunt. Phasellus nec rutrum dolor. Cras imperdiet sollicitudin arcu, id interdum nibh <a href="">fermentum</a> in. <li class="grid_4"><img src="http://placehold.it/1200x1000" alt="placeholder"></li>
</p> <li class="grid_2"><img src="http://placehold.it/350x200" alt="placeholder"></li>
<li class="grid_2"><img src="http://placehold.it/350x200" alt="placeholder"></li>
<li><img src="http://placehold.it/350x200" alt="placeholder"></li>
<li><img src="http://placehold.it/350x200" alt="placeholder"></li>
<li><img src="http://placehold.it/200x300" alt="placeholder"></li>
<li><img src="http://placehold.it/200x300" alt="placeholder"></li>
<li><img src="http://placehold.it/350x200" alt="placeholder"></li>
<li><img src="http://placehold.it/200x300" alt="placeholder"></li>
<li><img src="http://placehold.it/200x300" alt="placeholder"></li>
<li><img src="http://placehold.it/200x300" alt="placeholder"></li>
<li class="grid_4">
<p>Vestibulum consectetur sit amet nisi ut consectetur. Praesent efficitur, nibh vitae fringilla scelerisque, est neque faucibus quam, in iaculis purus libero eget mauris. Curabitur et luctus sapien, ac gravida orci. Aliquam erat volutpat. In hac habitasse platea dictumst. Aenean commodo, arcu a commodo efficitur, libero dolor mollis turpis, non posuere orci leo eget enim. Curabitur sit amet elementum orci, pulvinar dignissim urna. Morbi id ex eu ex congue laoreet. Aenean tincidunt dolor justo, semper pretium libero luctus nec. Ut vulputate metus accumsan leo imperdiet tincidunt. Phasellus nec rutrum dolor. Cras imperdiet sollicitudin arcu, id interdum nibh <a href="">fermentum</a> in.
<ul>
<li>One</li>
<li>Two</li>
</ul>
</p>
<p>Vestibulum consectetur sit amet nisi ut consectetur. Praesent efficitur, nibh vitae fringilla scelerisque, est neque faucibus quam, in iaculis purus libero eget mauris. Curabitur et luctus sapien, ac gravida orci. Aliquam erat volutpat. In hac habitasse platea dictumst. Aenean commodo, arcu a commodo efficitur, libero dolor mollis turpis, non posuere orci leo eget enim. Curabitur sit amet elementum orci, pulvinar dignissim urna. Morbi id ex eu ex congue laoreet. Aenean tincidunt dolor justo, semper pretium libero luctus nec. Ut vulputate metus accumsan leo imperdiet tincidunt. Phasellus nec rutrum dolor. Cras imperdiet sollicitudin arcu, id interdum nibh <a href="">fermentum</a> in.
</p>
</li>
</ul>
{% endblock %} {% endblock %}
{% block sidebar %} {% block sidebar %}
+1
View File
@@ -10,6 +10,7 @@
</p> </p>
{% endblock %} {% endblock %}
{% block sidebar %} {% block sidebar %}
{% include 'menu_plan.html' %} {% include 'menu_plan.html' %}
{% endblock %} {% endblock %}
+1
View File
@@ -10,6 +10,7 @@
</p> </p>
{% endblock %} {% endblock %}
{% block sidebar %} {% block sidebar %}
{% include 'menu_racing.html' %} {% include 'menu_racing.html' %}
{% endblock %} {% endblock %}
+1
View File
@@ -10,6 +10,7 @@
</p> </p>
{% endblock %} {% endblock %}
{% block sidebar %} {% block sidebar %}
{% include 'menu_workout.html' %} {% include 'menu_workout.html' %}
{% endblock %} {% endblock %}
+1
View File
@@ -10,6 +10,7 @@
</p> </p>
{% endblock %} {% endblock %}
{% block sidebar %} {% block sidebar %}
{% include 'menu_workouts.html' %} {% include 'menu_workouts.html' %}
{% endblock %} {% endblock %}
+12 -21
View File
@@ -1,27 +1,18 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% block title %}Contact Us - Thank You{% endblock title %} {% block title %}Contact Us - Thank You{% endblock title %}
{% block content %} {% block main %}
<h3>Thank you.</h3> <h1>Thank you for registering</h1>
<p>Thank you for registering. You can now login using the credential you provided. You can also view some of the videos below to get you started.</p> <p>Thank you for registering. You can now login using the credentials you provided. </p>
<p>Return <a href="/">home</a></p> <p>Return <a href="/">home</a></p>
<h3>Basic Navigation</h3>
<iframe width="560" height="315" src="https://www.youtube.com/embed/-rrTWTS23sM" frameborder="0" allowfullscreen></iframe>
<h3>Upload Page</h3>
<iframe width="560" height="315" src="https://www.youtube.com/embed/IsUtdh30USw" frameborder="0" allowfullscreen></iframe>
<h3>Integration with Strava, SportTracks or Concept2 logbook</h3>
<p><iframe width="560" height="315" src="https://www.youtube.com/embed/wF_P6x0uSL4" frameborder="0" allowfullscreen></iframe></p>
<p><iframe width="560" height="315" src="https://www.youtube.com/embed/rjNwXCh7jKg" frameborder="0" allowfullscreen></iframe></p>
<p><iframe width="560" height="315" src="https://www.youtube.com/embed/WfccMz3SbAc" frameborder="0" allowfullscreen></iframe></p>
<p><iframe width="560" height="315" src="https://www.youtube.com/embed/90AXO4dppT4" frameborder="0" allowfullscreen></iframe></p>
{% endblock content %} {% endblock main %}
{% block sidebar %}
{% include 'menu_help.html' %}
{% endblock %}
+17 -12
View File
@@ -1,12 +1,15 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}Contact Us{% endblock title %} {% block title %}Contact Us{% endblock title %}
{% block meta %} {% block meta %}
{% endblock %} {% endblock %}
{% block content %} {% block main %}
<div id="registrationform" class="grid_6 alpha"> <h1>New User Registration</h1>
<ul class="main-content">
<li class="grid_2">
<div id="registrationform">
{% if form.errors %} {% if form.errors %}
<p style="color: red;"> <p style="color: red;">
@@ -19,16 +22,13 @@
<table width=100%> <table width=100%>
{{ form.as_table }} {{ form.as_table }}
</table> </table>
<div class="grid_1 alpha"> <a href="/rowers/legal">Terms of Service</a>
<a class="button gray small" href="/rowers/legal">Terms of Service</a>
</div>
<div id="formbutton" class="grid_1 prefix_3 suffix_1 omega">
<input class="button green" type="submit" value="Submit"> <input class="button green" type="submit" value="Submit">
</div>
</form> </form>
</div> </div>
<div class="grid_6 omega"> </li>
<li class="grid_2">
<p> To use rowsandall, you need to register and agree with the Terms of Service. </p> <p> To use rowsandall, you need to register and agree with the Terms of Service. </p>
<p> Registration is free. </p> <p> Registration is free. </p>
@@ -39,7 +39,12 @@
<p>Also, we are restricting access to the site to 16 years and older <p>Also, we are restricting access to the site to 16 years and older
because of EU data protection regulations.</p> because of EU data protection regulations.</p>
</li>
</ul>
</div>
{% endblock content %}
{% endblock main %}
{% block sidebar %}
{% include 'menu_help.html' %}
{% endblock %}
+14 -17
View File
@@ -1,31 +1,28 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% block title %}Change Rower Export Settings{% endblock %} {% block title %}Change Rower Export Settings{% endblock %}
{% block content %} {% block main %}
<div class="grid_12 alpha"> <h1>Import and Export Settings for {{ rower.user.first_name }} {{ rower.user.last_name }}</h1>
<div class="grid_6 suffix_6 alpha"> {% if form.errors %}
<p> <p style="color: red;">
<h2>Export Settings</h2>
{% if form.errors %}
<p style="color: red;">
Please correct the error{{ form.errors|pluralize }} below. Please correct the error{{ form.errors|pluralize }} below.
</p> </p>
{% endif %} {% endif %}
<form enctype="multipart/form-data" action="" method="post"> <form enctype="multipart/form-data" action="" method="post">
<table> <table>
{{ form.as_table }} {{ form.as_table }}
</table> </table>
{% csrf_token %} {% csrf_token %}
<div class="grid_2 prefix_2 suffix_2">
<input class="button green" type="submit" value="Save"> <input class="button green" type="submit" value="Save">
</form> </form>
</p>
</div>
</div>
</div>
{% endblock %}
{% block sidebar %}
{% include 'menu_profile.html' %}
{% endblock %} {% endblock %}
+20 -190
View File
@@ -1,116 +1,24 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}Change Rower {% endblock %} {% block title %}Change Rower {% endblock %}
{% block content %} {% block main %}
<div class="grid_12 alpha"> <h1>User Settings for {{ rower.user.first_name }} {{ rower.user.last_name }}</h1>
<div class="grid_8 alpha">
<h1>User Settings for {{ rower.user.first_name }} {{ rower.user.last_name }}</h1>
<p><a href="http://analytics.rowsandall.com/2017/11/02/rowsandall-settings-page-tutorial/">Need help? Click to read the tutorial</a></p>
</div>
<div class="grid_2 suffix_2 omega dropdown">
<button class="grid_2 alpha button green small dropbtn">
{{ rower.user.first_name }} {{ rower.user.last_name }}
</button>
<div class="dropdown-content">
{% for rower in user|team_rowers %}
<a class="button green small" href="/rowers/rower/edit/{{ rower.id }}">{{ rower.user.first_name }} {{ rower.user.last_name }}</a>
{% endfor %}
</div>
</div>
<div class="grid_6 alpha">
<p>
<h2>Heart Rate Zones</h2>
<p>Set your heart rate zones with this form.</p>
{% if form.errors %}
<p style="color: red;">
Please correct the error{{ form.errors|pluralize }} below.
</p>
{% endif %}
<form enctype="multipart/form-data" action="" method="post"> <p><a href="http://analytics.rowsandall.com/2017/11/02/rowsandall-settings-page-tutorial/">Need help? Click to read the tutorial</a></p>
<table>
{{ form.as_table }}
</table>
{% csrf_token %}
<div class="grid_2 prefix_2 suffix_2">
<input class="button green" type="submit" value="Save">
</form>
</p>
</div>
</div>
<div class="grid_6 omega">
<p>
<h2>Power Zones</h2>
<p>The power zones are defined relative to power as measured by the
indoor rower.</p>
<form enctype="multipart/form-data" action="" method="post">
{% if powerzonesform.errors %}
<p style="color: red;">
Please correct the error{{ powerzonesform.errors|pluralize }} below.
{{ powerzonesform.non_field_errors }}
</p> <ul class="main-content">
{% endif %} <li class="grid_2">
<table>
<thead>
<tr>
<th>ID</th><th>Zone Name</th><th>Lower Boundary (Watt)</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td><td>{{ powerzonesform.ut3name }}</td>
<td></td>
</tr>
<tr>
<td>2</td><td>{{ powerzonesform.ut2name }}</td>
<td>{{ powerzonesform.pw_ut2 }}</td>
</tr>
<tr>
<td>3</td><td>{{ powerzonesform.ut1name }}</td>
<td>{{ powerzonesform.pw_ut1 }}</td>
</tr>
<tr>
<td>4</td><td>{{ powerzonesform.atname }}</td>
<td>{{ powerzonesform.pw_at }}</td>
</tr>
<tr>
<td>5</td><td>{{ powerzonesform.trname }}</td>
<td>{{ powerzonesform.pw_tr }}</td>
</tr>
<tr>
<td>6</td><td>{{ powerzonesform.anname }}</td>
<td>{{ powerzonesform.pw_an }}</td>
</tr>
</tbody>
</table>
{% csrf_token %}
<div class="grid_2 prefix_2 suffix_2">
<input class="button green" type="submit" value="Save">
</div>
</form>
</p>
</div>
</div>
<div class="grid_12 alpha">
<div class="grid_6 alpha">
<p>
<h2>Account Information</h2> <h2>Account Information</h2>
<div class="grid_6 alpha">
<div class="grid_2 suffix_4 alpha">
<p> <p>
{% if rower.user == user %} {% if rower.user == user %}
<a class="button gray small" href="/password_change/">Password Change</a> <a class="button blue small" href="/password_change/">Password Change</a>
{% else %} {% else %}
&nbsp; &nbsp;
{% endif %} {% endif %}
</p> </p>
</div>
</div>
</p>
{% if userform.errors %} {% if userform.errors %}
<p style="color: red;"> <p style="color: red;">
Please correct the error{{ form.errors|pluralize }} below. Please correct the error{{ form.errors|pluralize }} below.
@@ -133,108 +41,29 @@
</tr> </tr>
</table> </table>
{% csrf_token %} {% csrf_token %}
<div class="grid_2 alpha">
{% if rower.rowerplan == 'basic' and rower.user == user %} {% if rower.rowerplan == 'basic' and rower.user == user %}
<a class="button blue" href="/rowers/promembership">Upgrade</a> <a class="button blue" href="/rowers/promembership">Upgrade</a>
{% else %} {% else %}
&nbsp; &nbsp;
{% endif %} {% endif %}
</div>
<div class="grid_2 suffix_2 omega">
<input class="button green" type="submit" value="Save"> <input class="button green" type="submit" value="Save">
</form> </form>
</div> </li>
{% if rower.user == user %}
<li class="grid_2">
</p>
</div>
<div class="grid_6 omega">
<p>
<h2>Functional Threshold Power and OTW Slack</h2>
<p>Use this form to quickly change your zones based on the power of a
recent
full out 60 minutes effort on the ergometer.
It will update all zones defined above.</p>
<p>The OTW Power Slack is the percentage drop of your On-the-water
rowing power
vs the erg power. Typical values are around 15%. This will lower
the power zones for your OTW workouts.</p>
<form enctype="multipart/form-data" action="" method="post">
<table>
{{ powerform.as_table }}
</table>
{% csrf_token %}
<div class="grid_2 prefix_2 suffix_2">
<input class="button green" type="submit" value="Save">
</form>
</div>
</div>
</div>
{% if rower.user == user %}
<div class="grid_12 alpha">
<div class="grid_6 alpha">
<p>
<h2>Teams</h2>
<div class="grid_2 suffix_4 alpha">
<a class="button gray small" href="/rowers/me/teams">Manage Teams</a>
</div>
</p>
</div>
<div class="grid_6 omega">
<p>
<h2>Favorite Charts</h2>
<div class="grid_2 suffix_4 alpha">
<a class="button gray small" href="/rowers/me/favoritecharts">Manage Favorite Charts</a>
</div>
</p>
</div>
</div>
<div class="grid_12 alpha">
<div class="grid_6 alpha">
<p>
<h2>Export Settings</h2>
<div class="grid_2 suffix_4 alpha">
<a class="button gray small" href="/rowers/me/exportsettings">Manage Export Settings</a>
</div>
</p>
</div>
<div class="grid_6 omega">
<p>
<h2>Configure Workflow Layout</h2>
<div class="grid_2 suffix_4 alpha">
<a class="button gray small" href="/rowers/me/workflowconfig2">Manage Workflow Layout</a>
</div>
</p>
</div>
</div>
<div class="grid_12 alpha">
<div class="grid_6 alpha">
<p>
<h2>GDPR - Data Protection</h2> <h2>GDPR - Data Protection</h2>
<div class="grid_2 suffix_4 alpha">
<p> <p>
<a class="button gray small" href="/rowers/exportallworkouts">Download your data</a> <a class="button blue small" href="/rowers/exportallworkouts">Download your data</a>
</p> </p>
</div>
<div class="grid_2 suffix_4 alpha">
<p> <p>
<a class="button gray small" href="/rowers/me/deactivate">Deactivate Account</a> <a class="button blue small" href="/rowers/me/deactivate">Deactivate Account</a>
</p> </p>
</div>
<div class="grid_2 suffix_4 alpha">
<p> <p>
<a class="button red small" href="/rowers/me/delete">Delete Account</a> <a class="button red small" href="/rowers/me/delete">Delete Account</a>
</p> </p>
</div> </li>
</p> <li class="grid_2">
</div>
<div class="grid_6 omega">
{% if grants %} {% if grants %}
<p>
<h2>Applications</h2> <h2>Applications</h2>
<table width="100%"> <table width="100%">
<thead> <thead>
@@ -256,14 +85,15 @@
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
</p>
{% else %}
<p>&nbsp;</p>
{% endif %} {% endif %}
</div> </li>
</div> </ul>
{% endif %} {% endif %}
{% endblock %}
{% block sidebar %}
{% include 'menu_profile.html' %}
{% endblock %} {% endblock %}

Some files were not shown because too many files have changed in this diff Show More