source: OpenWorkouts-current/ow/templates/profile.pt @ c24991d

current
Last change on this file since c24991d was c24991d, checked in by Borja Lopez <borja@…>, 5 years ago

Fixed broken profile page when loading it using the user nickname

  • Property mode set to 100644
File size: 22.1 KB
Line 
1<html xmlns="http://www.w3.org/1999/xhtml"
2      xml:lang="en"
3      xmlns:tal="http://xml.zope.org/namespaces/tal"
4      xmlns:metal="http://xml.zope.org/namespaces/metal"
5      xmlns:i18n="http://xml.zope.org/namespaces/i18n"
6      i18n:domain="OpenWorkouts"
7      metal:use-macro="load: base.pt"
8      tal:attributes="lang request.locale_name">
9
10  <metal:head-title metal:fill-slot="head-title">
11    <tal:t i18n:translate="">My profile</tal:t>
12  </metal:head-title>
13
14  <metal:css metal:fill-slot="css">
15    <link rel="stylesheet" href="${request.static_url('ow:static/components/jquery-dropdown/jquery.dropdown.css')}" />
16  </metal:css>
17
18  <metal:content metal:fill-slot="content">
19
20    <div class="user-profile">
21      <div class="user-profile-account">
22        <div>
23          <tal:c tal:condition="getattr(user, 'picture', None)">
24            <img tal:attributes="src request.resource_path(user, 'picture', query={'size': 200})"
25                 width="450" />
26          </tal:c>
27          <div>
28            <h2>
29              <tal:fullname tal:content="user.fullname"></tal:fullname>
30            </h2>
31            <p>
32              <tal:has-nickname tal:condition="user.nickname">
33                <a href=""
34                   tal:attributes="href request.resource_url(request.root, 'profile', user.nickname)"
35                   tal:content="request.resource_url(request.root, 'profile', user.nickname)">
36                </a> |
37              </tal:has-nickname>
38              <span><tal:email tal:content="user.email"></tal:email></span>
39            </p>
40            <div class="profile-bio">
41              <p tal:repeat="paragraph getattr(user, 'bio', '').split('\n')"
42                 tal:content="paragraph"></p>
43            </div>
44            <ul class="workout-options">
45              <li><a href=""
46                     tal:attributes="href request.resource_url(user, 'edit')"
47                     i18n:translate="">edit profile</a></li>
48              <li><a href=""
49                     tal:attributes="href request.resource_url(user, 'passwd')"
50                     i18n:translate="">change password</a></li>
51            </ul>
52          </div>
53        </div>
54
55      </div>
56
57      <div class="workout-content">
58        <div class="workout-list">
59          <div class="total-workouts">
60            <span>
61              <tal:w tal:replace="len(workouts)"></tal:w>
62              <tal:t i18n:translate="">workouts</tal:t>
63            </span>
64            <span>
65              <tal:hms tal:define="hms timedelta_to_hms(totals['time'])">
66                <tal:h tal:content="str(hms[0]).zfill(2)"></tal:h>
67                <tal:t i18n:translate="">hours</tal:t>,
68                <tal:h tal:content="str(hms[1]).zfill(2)"></tal:h>
69                <tal:t i18n:translate="">min.</tal:t>
70              </tal:hms>
71            </span>
72            <span>
73              <tal:w tal:replace="round(totals['distance'])"></tal:w>
74              <tal:t i18n:translate="">km</tal:t>
75            </span>
76            <span>
77              <tal:w tal:replace="round(totals['elevation'])"></tal:w>
78              <tal:t i18n:translate="">m</tal:t>
79            </span>
80          </div>
81
82          <div class="month-stats js-month-stats">
83            <div class="svg-content">
84              <svg width="900" height="180" viewBox="0 0 900 180"></svg>
85            </div>
86            <div class="center">
87              <ul class="workout-options filters js-filters">
88                <li><a href="#" class="js-distance is-active" i18n:translate="">distance</a></li>
89                <li><a href="#" class="js-time" i18n:translate="">time</a></li>
90                <li><a href="#" class="js-elevation" i18n:translate="">elevation</a></li>
91              </ul>
92
93              <ul class="workout-options switcher js-switcher"
94                  tal:define="weekly 'week' in request.GET">
95                <li>
96                  <a href="#" class="" i18n:translate=""
97                     tal:attributes="class 'js-weekly is-active' if weekly else 'js-weekly'">
98                    weekly</a></li>
99                <li>
100                  <a href="#" class="" i18n:translate=""
101                     tal:attributes="class 'js-monthly is-active' if not weekly else 'js-monthly'">
102                    monthly</a></li>
103              </ul>
104            </div>
105          </div>
106
107
108          <tal:r tal:repeat="workout workouts">
109
110            <article class="workout-resume">
111
112              <h2 class="workout-title">
113                <a href="" tal:content="workout.title"
114                   tal:attributes="href request.resource_url(workout)"></a>
115              </h2>
116
117              <ul class="workout-info">
118                <li>
119                  <tal:c tal:content="workout.start_in_timezone(user.timezone)"></tal:c>
120                </li>
121                <li>
122                  <!--! use the properly formatted duration instead of the timedelta object -->
123                  <tal:c tal:content="workout._duration"></tal:c>
124                </li>
125                <li tal:condition="workout.distance">
126                  <tal:c tal:content="workout.rounded_distance"></tal:c> km
127                </li>
128                <li tal:condition="workout.uphill">
129                  +<tal:c tal:content="workout.uphill"></tal:c> m
130                </li>
131              </ul>
132
133              <ul class="workout-info" tal:define="hr workout.hr; cad workout.cad">
134                <li tal:condition="hr">
135                  <span i18n:translate="">HR (bpm)</span>:
136                  <tal:c tal:content="hr['avg']"></tal:c>
137                  <tal:t i18n:translate="">Avg.</tal:t>,
138                  <tal:c tal:content="hr['max']"></tal:c>
139                  <tal:t i18n:translate="">Max.</tal:t>
140                </li>
141                <li tal:condition="cad">
142                  <span i18n:translate="">Cad</span>:
143                  <tal:c tal:content="cad['avg']"></tal:c>
144                  <tal:t i18n:translate="">Avg.</tal:t>,
145                  <tal:c tal:content="cad['max']"></tal:c>
146                  <tal:t i18n:translate="">Max.</tal:t>
147                </li>
148              </ul>
149
150              <div class="workout-intro">
151                <p tal:repeat="paragraph workout.trimmed_notes.split('\n')"
152                   tal:content="paragraph"></p>
153              </div>
154
155              <div class="workout-map" tal:condition="workout.has_gpx">
156                <a href="" tal:attributes="href request.resource_url(workout)">
157                  <tal:has-screenshot tal:condition="workout.map_screenshot is not None">
158                    <img src="" tal:attributes="src request.static_url(workout.map_screenshot);
159                              alt workout.title; title workout.title">
160                  </tal:has-screenshot>
161                  <tal:has-not-screenshot tal:condition="workout.map_screenshot is None">
162                    <img src="" tal:attributes="src request.static_url('ow:static/media/img/no_map.gif');
163                              alt workout.title; title workout.title; class 'js-needs-map'">
164                  </tal:has-not-screenshot>
165                </a>
166              </div>
167
168            </article>
169
170          </tal:r>
171        </div>
172
173        <div class="workout-aside">
174
175          <h3 i18n:translate="">Profile info</h3>
176
177          <ul class="profile-data">
178            <li>
179              <span><tal:t i18n:translate="">Gender:</tal:t></span>
180              <tal:c tal:content="user_gender"></tal:c>
181            </li>
182            <li tal:define="birth_date getattr(user, 'birth_date', None)">
183              <span><tal:t i18n:translate="">Birth date:</tal:t></span>
184              <tal:c tal:condition="birth_date"
185                     tal:content="birth_date.strftime('%d/%m/%Y')"></tal:c>
186              <tal:c tal:condition="birth_date is None">-</tal:c>
187            </li>
188            <li>
189              <span><tal:t i18n:translate="">Height:</tal:t></span>
190              <tal:c tal:content="getattr(user, 'height', '-')"></tal:c> meters
191            </li>
192            <li>
193              <span><tal:t i18n:translate="">Weight:</tal:t></span>
194              <tal:c tal:content="getattr(user, 'weight', '-')"></tal:c> kg
195            </li>
196          </ul>
197
198          <tal:has-workouts tal:condition="profile_stats['sports']">
199
200            <h3 i18n:translate="">Workout stats</h3>
201
202            <p>
203              <a href="" data-jq-dropdown="#jq-dropdown-sports"
204                 class="profile-dropdown-sports js-jq-dropdown-sel-sports">
205                <strong tal:content="profile_stats['current_sport']"></strong>
206                <i class="arrow down"></i>
207              </a>
208            </p>
209
210            <tal:sports tal:repeat="sport profile_stats['sports']">
211              <div class="" tal:attributes="class 'js-sport-stats js-' + sport">
212
213                <a href="" data-jq-dropdown=""
214                   tal:attributes="data-jq-dropdown '#jq-dropdown-' + sport;
215                         class 'profile-dropdown-years js-jq-dropdown-sel-' + sport">
216                  <strong tal:content="profile_stats['current_year']"></strong>
217                  <i class="arrow down"></i>
218                </a>
219
220                <tal:years tal:repeat="year profile_stats['years']">
221                  <div class="" tal:attributes="class 'js-year-stats js-' + sport + '-' + str(year)">
222                    <ul class="profile-data"
223                        tal:define="sport_totals user.sport_totals(sport, year)">
224                      <li>
225                        <span>
226                          <tal:t i18n:translate="">Workouts</tal:t>
227                        </span>
228                        <tal:w tal:replace="sport_totals['workouts']"></tal:w>
229                      </li>
230                      <li>
231                        <span>
232                          <tal:t i18n:translate="">Time</tal:t>
233                        </span>
234                        <tal:hms tal:define="hms timedelta_to_hms(sport_totals['time'])">
235                          <tal:h tal:content="str(hms[0]).zfill(2)"></tal:h>
236                          <tal:t i18n:translate="">hours</tal:t>,
237                          <tal:h tal:content="str(hms[1]).zfill(2)"></tal:h>
238                          <tal:t i18n:translate="">min.</tal:t>
239                        </tal:hms>
240                      </li>
241                      <li>
242                        <span>
243                          <tal:t i18n:translate="">Distance</tal:t>
244                        </span>
245                        <tal:w tal:replace="round(sport_totals['distance'])"></tal:w>
246                        <tal:t i18n:translate="">km</tal:t>
247                      </li>
248                      <li>
249                        <span>
250                          <tal:t i18n:translate="">Elevation</tal:t>
251                        </span>
252                        <tal:w tal:replace="round(sport_totals['elevation'])"></tal:w>
253                        <tal:t i18n:translate="">m</tal:t>
254                      </li>
255                      <li><span i18n:translate="">Single workout records:</span></li>
256                      <li>
257                        <span>
258                          <tal:t i18n:translate="">Farthest distance</tal:t>
259                        </span>
260                        <tal:has-wid tal:condition="sport_totals['max_distance_wid'] is not None">
261                          <a href="" tal:attributes="href request.resource_url(user[sport_totals['max_distance_wid']])">
262                            <tal:w tal:replace="round(sport_totals['max_distance'])"></tal:w>
263                            <tal:t i18n:translate="">km</tal:t>
264                          </a>
265                        </tal:has-wid>
266                        <tal:has-not-wid tal:condition="sport_totals['max_distance_wid'] is None">
267                          <tal:w tal:replace="round(sport_totals['max_distance'])"></tal:w>
268                          <tal:t i18n:translate="">km</tal:t>
269                        </tal:has-not-wid>
270                      </li>
271                      <li>
272                        <span>
273                          <tal:t i18n:translate="">Longer workout</tal:t>
274                        </span>
275                        <tal:has-wid tal:condition="sport_totals['max_time_wid'] is not None">
276                          <a href="" tal:attributes="href request.resource_url(user[sport_totals['max_time_wid']])">
277                            <tal:hms tal:define="hms timedelta_to_hms(sport_totals['max_time'])">
278                              <tal:h tal:content="str(hms[0]).zfill(2)"></tal:h>
279                              <tal:t i18n:translate="">hours</tal:t>,
280                              <tal:h tal:content="str(hms[1]).zfill(2)"></tal:h>
281                              <tal:t i18n:translate="">min.</tal:t>
282                            </tal:hms>
283                          </a>
284                        </tal:has-wid>
285                        <tal:has-not-wid tal:condition="sport_totals['max_time_wid'] is None">
286                          <tal:hms tal:define="hms timedelta_to_hms(sport_totals['max_time'])">
287                            <tal:h tal:content="str(hms[0]).zfill(2)"></tal:h>
288                            <tal:t i18n:translate="">hours</tal:t>,
289                            <tal:h tal:content="str(hms[1]).zfill(2)"></tal:h>
290                            <tal:t i18n:translate="">min.</tal:t>
291                          </tal:hms>
292                        </tal:has-not-wid>
293                      </li>
294                      <li>
295                        <span>
296                          <tal:t i18n:translate="">Higher elevation gain</tal:t>
297                        </span>
298                        <tal:has-wid tal:condition="sport_totals['max_elevation_wid'] is not None">
299                          <a href="" tal:attributes="href request.resource_url(user[sport_totals['max_elevation_wid']])">
300                            <tal:w tal:replace="round(sport_totals['max_elevation'])"></tal:w>
301                            <tal:t i18n:translate="">m</tal:t>
302                          </a>
303                        </tal:has-wid>
304                        <tal:has-not-wid tal:condition="sport_totals['max_elevation_wid'] is None">
305                          <tal:w tal:replace="round(sport_totals['max_elevation'])"></tal:w>
306                          <tal:t i18n:translate="">m</tal:t>
307                        </tal:has-not-wid>
308                      </li>
309                    </ul>
310                  </div>
311                </tal:years>
312
313                <strong i18n:translate="">All time</strong>
314                <ul class="profile-data"
315                    tal:define="sport_totals user.sport_totals(sport)">
316                  <li>
317                    <span>
318                      <tal:t i18n:translate="">Workouts</tal:t>
319                    </span>
320                    <tal:w tal:replace="sport_totals['workouts']"></tal:w>
321                  </li>
322                  <li>
323                    <span>
324                      <tal:t i18n:translate="">Time</tal:t>
325                    </span>
326                    <tal:hms tal:define="hms timedelta_to_hms(sport_totals['time'])">
327                      <tal:h tal:content="str(hms[0]).zfill(2)"></tal:h>
328                      <tal:t i18n:translate="">hours</tal:t>,
329                      <tal:h tal:content="str(hms[1]).zfill(2)"></tal:h>
330                      <tal:t i18n:translate="">min.</tal:t>
331                    </tal:hms>
332                  </li>
333                  <li>
334                    <span>
335                      <tal:t i18n:translate="">Distance</tal:t>
336                    </span>
337                    <tal:w tal:replace="round(sport_totals['distance'])"></tal:w>
338                    <tal:t i18n:translate="">km</tal:t>
339                  </li>
340                  <li>
341                    <span>
342                      <tal:t i18n:translate="">Elevation</tal:t>
343                    </span>
344                    <tal:w tal:replace="round(sport_totals['elevation'])"></tal:w>
345                    <tal:t i18n:translate="">m</tal:t>
346                  </li>
347                  <li><span i18n:translate="">Single workout records:</span></li>
348                  <li>
349                    <span>
350                      <tal:t i18n:translate="">Farthest distance</tal:t>
351                    </span>
352                    <tal:has-wid tal:condition="sport_totals['max_distance_wid'] is not None">
353                      <a href="" tal:attributes="href request.resource_url(user[sport_totals['max_distance_wid']])">
354                        <tal:w tal:replace="round(sport_totals['max_distance'])"></tal:w>
355                        <tal:t i18n:translate="">km</tal:t>
356                      </a>
357                    </tal:has-wid>
358                    <tal:has-not-wid tal:condition="sport_totals['max_distance_wid'] is None">
359                      <tal:w tal:replace="round(sport_totals['max_distance'])"></tal:w>
360                      <tal:t i18n:translate="">km</tal:t>
361                    </tal:has-not-wid>
362                  </li>
363                  <li>
364                    <span>
365                      <tal:t i18n:translate="">Longer workout</tal:t>
366                    </span>
367                    <tal:has-wid tal:condition="sport_totals['max_time_wid'] is not None">
368                      <a href="" tal:attributes="href request.resource_url(user[sport_totals['max_time_wid']])">
369                        <tal:hms tal:define="hms timedelta_to_hms(sport_totals['max_time'])">
370                          <tal:h tal:content="str(hms[0]).zfill(2)"></tal:h>
371                          <tal:t i18n:translate="">hours</tal:t>,
372                          <tal:h tal:content="str(hms[1]).zfill(2)"></tal:h>
373                          <tal:t i18n:translate="">min.</tal:t>
374                        </tal:hms>
375                      </a>
376                    </tal:has-wid>
377                    <tal:has-not-wid tal:condition="sport_totals['max_time_wid'] is None">
378                      <tal:hms tal:define="hms timedelta_to_hms(sport_totals['max_time'])">
379                        <tal:h tal:content="str(hms[0]).zfill(2)"></tal:h>
380                        <tal:t i18n:translate="">hours</tal:t>,
381                        <tal:h tal:content="str(hms[1]).zfill(2)"></tal:h>
382                        <tal:t i18n:translate="">min.</tal:t>
383                      </tal:hms>
384                    </tal:has-not-wid>
385                  </li>
386                  <li>
387                    <span>
388                      <tal:t i18n:translate="">Higher elevation gain</tal:t>
389                    </span>
390                    <tal:has-wid tal:condition="sport_totals['max_elevation_wid'] is not None">
391                      <a href="" tal:attributes="href request.resource_url(user[sport_totals['max_elevation_wid']])">
392                        <tal:w tal:replace="round(sport_totals['max_elevation'])"></tal:w>
393                        <tal:t i18n:translate="">m</tal:t>
394                      </a>
395                    </tal:has-wid>
396                    <tal:has-not-wid tal:condition="sport_totals['max_elevation_wid'] is None">
397                      <tal:w tal:replace="round(sport_totals['max_elevation'])"></tal:w>
398                      <tal:t i18n:translate="">m</tal:t>
399                    </tal:has-not-wid>
400                  </li>
401                </ul>
402              </div>
403            </tal:sports>
404
405          </tal:has-workouts>
406
407        </div>
408      </div>
409    </div>
410
411      <div id="jq-dropdown-sports" class="jq-dropdown jq-dropdown-tip">
412        <ul class="jq-dropdown-menu">
413          <tal:sports tal:repeat="sport profile_stats['sports']">
414            <li>
415              <a href="#" class="" tal:content="sport"
416                 tal:attributes="class 'js-choose-sport-stats js-' + sport">
417              </a>
418            </li>
419          </tal:sports>
420        </ul>
421      </div>
422
423
424    <tal:sports tal:repeat="sport profile_stats['sports']">
425      <div id="" class="jq-dropdown jq-dropdown-tip"
426           tal:attributes="id 'jq-dropdown-' + sport">
427        <ul class="jq-dropdown-menu">
428          <tal:years tal:repeat="year profile_stats['years']">
429            <li>
430              <a href="#" class="" tal:content="year"
431                 tal:attributes="class 'js-choose-year-stats js-' + sport + '-' + str(year)">
432              </a>
433            </li>
434          </tal:years>
435        </ul>
436      </div>
437    </tal:sports>
438
439
440  </metal:content>
441
442  <metal:body-js metal:fill-slot="body-js">
443
444    <script src="${request.static_url('ow:static/components/jquery-dropdown/jquery.dropdown.js')}"></script>
445    <script src="${request.static_url('ow:static/components/d3/d3.min.js')}"></script>
446    <script src="${request.static_url('ow:static/js/ow.js')}"></script>
447
448    <script type="text/javascript">
449     var map_shots = owjs.map_shots({
450         img_selector: 'img.js-needs-map',
451     })
452     map_shots.run();
453
454     var sport_stats = owjs.sport_stats({
455         link_selector: 'a.js-choose-sport-stats',
456         stats_selector: 'div.js-sport-stats',
457         selected: 'div.js-sport-stats.js-${profile_stats['current_sport']}',
458         dropdown_selector: 'a.js-jq-dropdown-sel-sports',
459         current_year: '${profile_stats['current_year']}',
460         year_link_selector: 'a.js-choose-year-stats.js-'
461     })
462     sport_stats.setup();
463
464     var year_stats = owjs.year_stats({
465         link_selector: 'a.js-choose-year-stats',
466         stats_selector: 'div.js-year-stats',
467         selected: 'div.js-year-stats.js-${profile_stats['current_sport']}-${profile_stats['current_year']}',
468         dropdown_selector: 'a.js-jq-dropdown-sel-'
469     })
470     year_stats.setup();
471
472     var y_axis_labels = {
473         "distance": "Kilometers",
474         "time": "Hours",
475         "elevation": "Meters"
476     };
477
478     var year_chart = owjs.year_chart({
479         chart_selector: '.js-month-stats svg',
480         filters_selector: '.js-month-stats .js-filters a',
481         switcher_selector: '.js-month-stats .js-switcher a',
482         is_active_class: 'is-active',
483         urls: {"monthly": "${request.resource_url(user, 'monthly')}",
484                "weekly": "${request.resource_url(user, 'weekly')}"},
485         current_month: "${current_month}",
486         current_week: "${current_week}",
487         y_axis_labels: y_axis_labels,
488         filter_by: "distance",
489         url: "${'monthly' if current_week is None else 'weekly'}",
490     });
491     year_chart.render("distance", "${'monthly' if current_week is None else 'weekly'}");
492     year_chart.filters_setup();
493     year_chart.switcher_setup();
494    </script>
495
496  </metal:body-js>
497
498</html>
Note: See TracBrowser for help on using the repository browser.