Client - update workout card on timeline and workout detail
This commit is contained in:
		
							
								
								
									
										67
									
								
								fittrackee_client/public/img/workouts/map.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								fittrackee_client/public/img/workouts/map.svg
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,67 @@
 | 
			
		||||
<?xml version="1.0" encoding="iso-8859-1"?>
 | 
			
		||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
 | 
			
		||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
 | 
			
		||||
	 viewBox="0 0 512.002 512.002" style="enable-background:new 0 0 512.002 512.002;" xml:space="preserve">
 | 
			
		||||
<g>
 | 
			
		||||
	<g>
 | 
			
		||||
		<path fill="#2c3e50" opacity="0.1" d="M511.89,475.873l-29.997-165.398c-0.74-4.084-4.651-6.795-8.735-6.054c-4.084,0.74-6.793,4.652-6.053,8.735l12.683,69.933
 | 
			
		||||
			l-97.782-113.58l65.766-14.678l9.738,5.421l4.228,23.316c0.74,4.084,4.651,6.793,8.735,6.054c4.084-0.74,6.793-4.652,6.054-8.735
 | 
			
		||||
			l-4.864-26.814c-0.401-2.214-1.773-4.131-3.738-5.225l-15.343-8.541c0,0,0,0-0.001,0l-48.488-26.991h-0.001L366.68,192.49
 | 
			
		||||
			c-0.001,0-0.002-0.001-0.002-0.001c-0.003-0.001-0.005-0.003-0.008-0.005c-0.289-0.16-0.585-0.298-0.888-0.417
 | 
			
		||||
			c-0.095-0.037-0.192-0.062-0.289-0.095c-0.211-0.074-0.423-0.145-0.638-0.2c-0.122-0.031-0.245-0.049-0.369-0.073
 | 
			
		||||
			c-0.193-0.038-0.387-0.076-0.582-0.099c-0.132-0.016-0.263-0.021-0.396-0.029c-0.189-0.012-0.378-0.022-0.567-0.02
 | 
			
		||||
			c-0.135,0.001-0.269,0.011-0.404,0.019c-0.186,0.012-0.372,0.029-0.558,0.055c-0.135,0.019-0.27,0.043-0.404,0.07
 | 
			
		||||
			c-0.182,0.036-0.362,0.078-0.542,0.127c-0.135,0.037-0.269,0.077-0.402,0.121c-0.174,0.059-0.346,0.126-0.517,0.198
 | 
			
		||||
			c-0.132,0.056-0.263,0.111-0.394,0.175c-0.057,0.028-0.116,0.047-0.172,0.076l-17.168,8.949
 | 
			
		||||
			c12.772-23.815,19.224-46.88,19.224-68.946c0-57.965-47.158-105.123-105.123-105.123S151.364,74.43,151.364,132.395
 | 
			
		||||
			c0,22.28,6.572,45.579,19.594,69.64l-18.499-9.643c-0.057-0.03-0.118-0.05-0.176-0.078c-0.126-0.062-0.256-0.116-0.384-0.17
 | 
			
		||||
			c-0.173-0.073-0.348-0.141-0.525-0.201c-0.131-0.044-0.264-0.083-0.397-0.12c-0.18-0.049-0.361-0.092-0.543-0.128
 | 
			
		||||
			c-0.135-0.027-0.271-0.051-0.407-0.07c-0.183-0.026-0.367-0.042-0.551-0.054c-0.138-0.009-0.276-0.018-0.413-0.02
 | 
			
		||||
			c-0.184-0.002-0.367,0.008-0.551,0.019c-0.138,0.009-0.276,0.014-0.414,0.031c-0.187,0.022-0.372,0.059-0.557,0.095
 | 
			
		||||
			c-0.131,0.026-0.263,0.045-0.393,0.078c-0.205,0.052-0.406,0.121-0.607,0.19c-0.105,0.036-0.212,0.064-0.317,0.105
 | 
			
		||||
			c-0.302,0.119-0.597,0.257-0.885,0.416c-0.003,0.001-0.005,0.003-0.008,0.005c-0.001,0-0.001,0.001-0.002,0.001L44.086,248.848
 | 
			
		||||
			c-1.966,1.094-3.338,3.011-3.738,5.225L11.831,411.308c-0.74,4.083,1.97,7.995,6.054,8.735c4.085,0.743,7.995-1.97,8.735-6.054
 | 
			
		||||
			l8.555-47.171l97.261-51.414l-7.822,100.994L17.457,464.513l3.771-20.8c0.74-4.083-1.969-7.994-6.053-8.735
 | 
			
		||||
			c-4.081-0.738-7.994,1.97-8.735,6.054l-6.319,34.842c-0.498,2.744,0.566,5.539,2.762,7.258c1.347,1.054,2.982,1.597,4.632,1.597
 | 
			
		||||
			c1.043,0,2.092-0.217,3.077-0.659l121.168-54.405l121.117,54.382c0.003,0.001,0.006,0.003,0.009,0.004l0.041,0.018
 | 
			
		||||
			c0.068,0.031,0.139,0.052,0.209,0.081c0.111,0.046,0.223,0.089,0.337,0.13c0.109,0.039,0.219,0.078,0.331,0.112
 | 
			
		||||
			c0.072,0.022,0.144,0.041,0.216,0.061c0.094,0.026,0.187,0.051,0.283,0.073c0.156,0.036,0.314,0.064,0.471,0.09
 | 
			
		||||
			c0.075,0.012,0.149,0.03,0.225,0.04c0.051,0.007,0.102,0.014,0.153,0.02c0.251,0.029,0.505,0.044,0.757,0.047
 | 
			
		||||
			c0.032,0,0.064,0.006,0.096,0.006c0.016,0,0.032-0.003,0.048-0.003c0.304-0.002,0.606-0.027,0.909-0.066
 | 
			
		||||
			c0.037-0.005,0.075-0.003,0.113-0.009c0.057-0.008,0.113-0.027,0.171-0.036c0.235-0.039,0.47-0.09,0.702-0.153
 | 
			
		||||
			c0.064-0.017,0.129-0.027,0.193-0.045c0.007-0.002,0.013-0.002,0.02-0.004c0.021-0.006,0.04-0.017,0.061-0.024
 | 
			
		||||
			c0.292-0.09,0.579-0.193,0.862-0.32l121.164-54.405l121.167,54.404c0.117,0.052,0.237,0.091,0.357,0.137
 | 
			
		||||
			c0.118,0.046,0.234,0.097,0.355,0.137c0.157,0.052,0.318,0.091,0.478,0.132c0.099,0.026,0.195,0.058,0.296,0.079
 | 
			
		||||
			c0.193,0.042,0.388,0.069,0.583,0.096c0.07,0.009,0.138,0.025,0.208,0.033c0.267,0.029,0.534,0.044,0.801,0.044h0.001
 | 
			
		||||
			c0.001,0,0.002,0,0.002,0c0.365,0,0.73-0.037,1.094-0.09c0.084-0.012,0.168-0.025,0.252-0.041
 | 
			
		||||
			c0.359-0.065,0.715-0.149,1.067-0.269c0.022-0.008,0.044-0.019,0.066-0.026c0.232-0.081,0.463-0.17,0.689-0.277
 | 
			
		||||
			c0.066-0.031,0.123-0.075,0.188-0.108c0.189-0.095,0.371-0.204,0.553-0.317c0.182-0.111,0.363-0.223,0.534-0.35
 | 
			
		||||
			c0.059-0.044,0.125-0.075,0.184-0.12c0.132-0.103,0.247-0.222,0.371-0.334c0.099-0.089,0.202-0.173,0.297-0.266
 | 
			
		||||
			c0.228-0.225,0.436-0.465,0.629-0.714c0.036-0.047,0.079-0.088,0.115-0.136c0.224-0.304,0.422-0.623,0.597-0.955
 | 
			
		||||
			c0.049-0.093,0.086-0.192,0.132-0.288c0.116-0.244,0.223-0.49,0.313-0.745c0.045-0.128,0.081-0.258,0.119-0.39
 | 
			
		||||
			c0.068-0.234,0.125-0.471,0.17-0.712c0.026-0.138,0.05-0.277,0.068-0.417c0.033-0.255,0.048-0.514,0.055-0.773
 | 
			
		||||
			c0.003-0.123,0.013-0.245,0.01-0.37C511.993,476.646,511.961,476.259,511.89,475.873z M379.797,216.992l-7.704,1.802l-0.493-6.365
 | 
			
		||||
			L379.797,216.992z M363.403,301.218l-31.384-24.505c-2.172-1.695-5.096-2.067-7.624-0.968l-60.844,26.482v-8.235
 | 
			
		||||
			c4.546-3.703,14.875-12.433,27.255-24.962l67.797-29.784L363.403,301.218z M356.413,210.978l0.96,12.392l-42.353,18.607
 | 
			
		||||
			c4.205-5.213,8.126-10.398,11.765-15.555L356.413,210.978z M155.598,210.978l31.15,16.238c4.613,6.487,9.666,13.021,15.173,19.598
 | 
			
		||||
			c4.815,5.75,9.614,11.093,14.231,15.984l-63.86-9.138L155.598,210.978z M133.808,297.678l-95.224,50.336l4.638-25.574l0.119-0.659
 | 
			
		||||
			l92.37-48.681L133.808,297.678z M137.084,255.388l-90.335,47.609l7.752-42.744l85.91-47.823l-2.159,27.881L137.084,255.388z
 | 
			
		||||
			 M139.662,416.737l7.115-91.869l88.77,134.922L139.662,416.737z M248.49,387.773l-46.293-72.958l46.293,5.543V387.773z
 | 
			
		||||
			 M248.49,305.22l-60.229-7.211c-2.879-0.339-5.704,1-7.251,3.456c-1.547,2.455-1.542,5.581,0.013,8.033l67.467,106.328v36.294
 | 
			
		||||
			l-99.819-151.715l2.458-31.728l82.913,11.864c6.253,5.803,11.322,10.112,14.447,12.685V305.22z M256.487,280.303
 | 
			
		||||
			c-18.977-16.005-90.093-80.494-90.093-147.907c-0.001-49.678,40.415-90.094,90.093-90.094s90.094,40.416,90.094,90.094
 | 
			
		||||
			C346.581,199.809,275.464,264.299,256.487,280.303z M263.52,465.602v-33.357l22.466,23.269L263.52,465.602z M300.56,448.97
 | 
			
		||||
			l-37.04-38.364v-91.976l62.772-27.32l38.681,30.203l7.375,95.224L300.56,448.97z M373.266,233.953l26.055-6.093l18.478,10.286
 | 
			
		||||
			l10.224,5.692l-53.075,11.845L373.266,233.953z M387.397,416.398l-5.867-75.75l96.54,116.464L387.397,416.398z M379.519,314.671
 | 
			
		||||
			l-2.042-26.37l-0.086-1.117l107.69,125.09l6.905,38.073L379.519,314.671z"/>
 | 
			
		||||
	</g>
 | 
			
		||||
</g>
 | 
			
		||||
<g>
 | 
			
		||||
	<g>
 | 
			
		||||
		<path fill="#2c3e50" opacity="0.1" d="M256.487,85.95c-4.15,0-7.515,3.364-7.515,7.515s3.365,7.515,7.515,7.515c17.323,0,31.416,14.093,31.416,31.416
 | 
			
		||||
			c0,17.322-14.093,31.416-31.416,31.416s-31.416-14.093-31.416-31.416c0-8.287,3.198-16.106,9.006-22.018
 | 
			
		||||
			c2.909-2.96,2.867-7.718-0.094-10.626c-2.961-2.909-7.719-2.868-10.627,0.094c-8.586,8.739-13.314,20.299-13.314,32.55
 | 
			
		||||
			c0,25.61,20.835,46.446,46.446,46.446s46.446-20.836,46.446-46.446C302.933,106.785,282.098,85.95,256.487,85.95z"/>
 | 
			
		||||
	</g>
 | 
			
		||||
</g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 6.6 KiB  | 
| 
		 Before Width: | Height: | Size: 888 B After Width: | Height: | Size: 888 B  | 
@@ -3,9 +3,7 @@
 | 
			
		||||
    <div
 | 
			
		||||
      class="bg-map-image"
 | 
			
		||||
      :style="{
 | 
			
		||||
        backgroundImage: `url(${getApiUrl()}workouts/map/${
 | 
			
		||||
          workout.map
 | 
			
		||||
        }?${Date.now()})`,
 | 
			
		||||
        backgroundImage: `url(${getApiUrl()}workouts/map/${workout.map})`,
 | 
			
		||||
      }"
 | 
			
		||||
    />
 | 
			
		||||
    <div class="map-attribution">
 | 
			
		||||
 
 | 
			
		||||
@@ -13,10 +13,13 @@
 | 
			
		||||
            <div v-else class="no-picture">
 | 
			
		||||
              <i class="fa fa-user-circle-o" aria-hidden="true" />
 | 
			
		||||
            </div>
 | 
			
		||||
            <span class="workout-user-name">{{ user.username }}</span>
 | 
			
		||||
            <span v-if="user.username" class="workout-user-name">
 | 
			
		||||
              {{ user.username }}
 | 
			
		||||
            </span>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div
 | 
			
		||||
            class="workout-date"
 | 
			
		||||
            v-if="workout && user"
 | 
			
		||||
            :title="
 | 
			
		||||
              format(
 | 
			
		||||
                getDateWithTZ(workout.workout_date, user.timezone),
 | 
			
		||||
@@ -34,12 +37,22 @@
 | 
			
		||||
        </div>
 | 
			
		||||
        <div
 | 
			
		||||
          class="workout-map"
 | 
			
		||||
          v-if="workout.with_gpx"
 | 
			
		||||
          :class="{ 'no-cursor': !workout }"
 | 
			
		||||
          @click="
 | 
			
		||||
            $router.push({ name: 'Workout', params: { workoutId: workout.id } })
 | 
			
		||||
            workout
 | 
			
		||||
              ? $router.push({
 | 
			
		||||
                  name: 'Workout',
 | 
			
		||||
                  params: { workoutId: workout.id },
 | 
			
		||||
                })
 | 
			
		||||
              : null
 | 
			
		||||
          "
 | 
			
		||||
        >
 | 
			
		||||
          <StaticMap :workout="workout"></StaticMap>
 | 
			
		||||
          <div v-if="workout">
 | 
			
		||||
            <StaticMap v-if="workout.with_gpx" :workout="workout" />
 | 
			
		||||
            <div v-else class="no-map">
 | 
			
		||||
              {{ t('workouts.NO_MAP') }}
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div
 | 
			
		||||
          class="workout-data"
 | 
			
		||||
@@ -48,15 +61,20 @@
 | 
			
		||||
          "
 | 
			
		||||
        >
 | 
			
		||||
          <div>
 | 
			
		||||
            <img class="sport-img" alt="workout sport logo" :src="sport.img" />
 | 
			
		||||
            <img
 | 
			
		||||
              v-if="sport"
 | 
			
		||||
              class="sport-img"
 | 
			
		||||
              alt="workout sport logo"
 | 
			
		||||
              :src="sport.img"
 | 
			
		||||
            />
 | 
			
		||||
          </div>
 | 
			
		||||
          <div>
 | 
			
		||||
            <i class="fa fa-clock-o" aria-hidden="true" />
 | 
			
		||||
            {{ workout.moving }}
 | 
			
		||||
            <span v-if="workout">{{ workout.moving }}</span>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div>
 | 
			
		||||
            <i class="fa fa-road" aria-hidden="true" />
 | 
			
		||||
            {{ workout.distance }} km
 | 
			
		||||
            <span v-if="workout">{{ workout.distance }} km</span>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </template>
 | 
			
		||||
@@ -88,7 +106,7 @@
 | 
			
		||||
    props: {
 | 
			
		||||
      workout: {
 | 
			
		||||
        type: Object as PropType<IWorkout>,
 | 
			
		||||
        required: true,
 | 
			
		||||
        required: false,
 | 
			
		||||
      },
 | 
			
		||||
      user: {
 | 
			
		||||
        type: Object as PropType<IAuthUserProfile>,
 | 
			
		||||
@@ -96,12 +114,13 @@
 | 
			
		||||
      },
 | 
			
		||||
      sport: {
 | 
			
		||||
        type: Object as PropType<ISport>,
 | 
			
		||||
        required: true,
 | 
			
		||||
        required: false,
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
    setup(props) {
 | 
			
		||||
      const { t } = useI18n()
 | 
			
		||||
      const store = useStore()
 | 
			
		||||
 | 
			
		||||
      const userPictureUrl: ComputedRef<string> = computed(() =>
 | 
			
		||||
        props.user.picture
 | 
			
		||||
          ? `${getApiUrl()}/users/${props.user.username}/picture?${Date.now()}`
 | 
			
		||||
@@ -157,6 +176,18 @@
 | 
			
		||||
            font-style: italic;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .workout-map {
 | 
			
		||||
          background-color: var(--workout-no-map-bg-color);
 | 
			
		||||
          height: 150px;
 | 
			
		||||
          .no-map {
 | 
			
		||||
            line-height: 150px;
 | 
			
		||||
          }
 | 
			
		||||
          .bg-map-image {
 | 
			
		||||
            height: 150px;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .workout-data {
 | 
			
		||||
          display: flex;
 | 
			
		||||
          padding-top: $default-padding * 0.5;
 | 
			
		||||
@@ -173,6 +204,12 @@
 | 
			
		||||
        .workout-data {
 | 
			
		||||
          cursor: pointer;
 | 
			
		||||
        }
 | 
			
		||||
        .no-cursor {
 | 
			
		||||
          cursor: default;
 | 
			
		||||
        }
 | 
			
		||||
        .fa {
 | 
			
		||||
          padding-right: $default-padding;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -2,12 +2,16 @@
 | 
			
		||||
  <div class="timeline">
 | 
			
		||||
    <div class="section-title">{{ t('workouts.LATEST_WORKOUTS') }}</div>
 | 
			
		||||
    <WorkoutCard
 | 
			
		||||
      v-for="workout in workouts"
 | 
			
		||||
      :workout="workout"
 | 
			
		||||
      :sport="sports.filter((s) => s.id === workout.sport_id)[0]"
 | 
			
		||||
      v-for="index in [...Array(displayedWorkoutsCount).keys()]"
 | 
			
		||||
      :workout="workouts.length > 0 ? workouts[index] : null"
 | 
			
		||||
      :sport="
 | 
			
		||||
        workouts.length > 0
 | 
			
		||||
          ? sports.filter((s) => s.id === workouts[index].sport_id)[0]
 | 
			
		||||
          : null
 | 
			
		||||
      "
 | 
			
		||||
      :user="user"
 | 
			
		||||
      :key="workout.id"
 | 
			
		||||
    ></WorkoutCard>
 | 
			
		||||
      :key="index"
 | 
			
		||||
    />
 | 
			
		||||
    <div v-if="workouts.length === 0" class="no-workouts">
 | 
			
		||||
      {{ t('workouts.NO_WORKOUTS') }}
 | 
			
		||||
    </div>
 | 
			
		||||
@@ -16,11 +20,11 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
  import {
 | 
			
		||||
    computed,
 | 
			
		||||
    ComputedRef,
 | 
			
		||||
    PropType,
 | 
			
		||||
    computed,
 | 
			
		||||
    defineComponent,
 | 
			
		||||
    onBeforeMount,
 | 
			
		||||
    PropType,
 | 
			
		||||
  } from 'vue'
 | 
			
		||||
  import { useI18n } from 'vue-i18n'
 | 
			
		||||
 | 
			
		||||
@@ -46,19 +50,25 @@
 | 
			
		||||
        required: true,
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
    setup() {
 | 
			
		||||
    setup(props) {
 | 
			
		||||
      const store = useStore()
 | 
			
		||||
      const { t } = useI18n()
 | 
			
		||||
 | 
			
		||||
      const per_page = 5
 | 
			
		||||
      const displayedWorkoutsCount =
 | 
			
		||||
        props.user.nb_workouts >= per_page ? per_page : props.user.nb_workouts
 | 
			
		||||
      onBeforeMount(() =>
 | 
			
		||||
        store.dispatch(WORKOUTS_STORE.ACTIONS.GET_USER_WORKOUTS, { page: 1 })
 | 
			
		||||
        store.dispatch(WORKOUTS_STORE.ACTIONS.GET_USER_WORKOUTS, {
 | 
			
		||||
          page: 1,
 | 
			
		||||
          per_page,
 | 
			
		||||
        })
 | 
			
		||||
      )
 | 
			
		||||
 | 
			
		||||
      const workouts: ComputedRef<IWorkout[]> = computed(
 | 
			
		||||
        () => store.getters[WORKOUTS_STORE.GETTERS.USER_WORKOUTS]
 | 
			
		||||
      )
 | 
			
		||||
 | 
			
		||||
      return { workouts, t }
 | 
			
		||||
      return { displayedWorkoutsCount, per_page, workouts, t }
 | 
			
		||||
    },
 | 
			
		||||
  })
 | 
			
		||||
</script>
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,7 @@
 | 
			
		||||
      class="workout-data"
 | 
			
		||||
      v-if="workoutObject.maxAlt !== null && workoutObject.minAlt !== null"
 | 
			
		||||
    >
 | 
			
		||||
      <img class="mountains" src="/img/misc/mountains.svg" />
 | 
			
		||||
      <img class="mountains" src="/img/workouts/mountains.svg" />
 | 
			
		||||
      {{ t('workouts.MIN_ALTITUDE') }}: <span>{{ workoutObject.minAlt }} m</span
 | 
			
		||||
      ><br />
 | 
			
		||||
      {{ t('workouts.MAX_ALTITUDE') }}:
 | 
			
		||||
 
 | 
			
		||||
@@ -138,12 +138,7 @@
 | 
			
		||||
      width: 600px;
 | 
			
		||||
    }
 | 
			
		||||
    .no-map {
 | 
			
		||||
      text-align: center;
 | 
			
		||||
      vertical-align: center;
 | 
			
		||||
      font-style: italic;
 | 
			
		||||
      line-height: 400px;
 | 
			
		||||
      color: var(--workout-no-map-color);
 | 
			
		||||
      background-color: var(--workout-no-map-bg-color);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @media screen and (max-width: $small-limit) {
 | 
			
		||||
 
 | 
			
		||||
@@ -101,3 +101,16 @@ button {
 | 
			
		||||
  padding-left: $default-padding;
 | 
			
		||||
  text-transform: capitalize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.no-map {
 | 
			
		||||
  background-color: var(--workout-no-map-bg-color);
 | 
			
		||||
  background-image: url('/img/workouts/map.svg');
 | 
			
		||||
  background-size: contain;
 | 
			
		||||
  background-repeat: no-repeat;
 | 
			
		||||
  background-position: center;
 | 
			
		||||
  color: var(--workout-no-map-color);
 | 
			
		||||
  font-style: italic;
 | 
			
		||||
  font-weight: bold;
 | 
			
		||||
  text-align: center;
 | 
			
		||||
  vertical-align: center;
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user