= {
Running: '#926692',
Walking: '#929292',
}
+
+const sortSports = (a: ISport, b: ISport): number => {
+ const sportALabel = a.label.toLowerCase()
+ const sportBLabel = b.label.toLowerCase()
+ return sportALabel > sportBLabel ? 1 : sportALabel < sportBLabel ? -1 : 0
+}
+
+export const translateSports = (
+ sports: ISport[],
+ t: CallableFunction,
+ onlyActive = false
+): ISport[] =>
+ sports
+ .filter((sport) => (onlyActive ? sport.is_active : true))
+ .map((sport) => ({
+ ...sport,
+ label: t(`sports.${sport.label}.LABEL`),
+ }))
+ .sort(sortSports)
diff --git a/fittrackee_client/src/views/DashBoard.vue b/fittrackee_client/src/views/DashBoard.vue
index c9049267..8f56ec52 100644
--- a/fittrackee_client/src/views/DashBoard.vue
+++ b/fittrackee_client/src/views/DashBoard.vue
@@ -7,7 +7,7 @@
-
+
@@ -22,7 +22,7 @@
import Timeline from '@/components/Dashboard/Timeline/index.vue'
import UserCalendar from '@/components/Dashboard/UserCalendar/index.vue'
import UserMonthStats from '@/components/Dashboard/UserMonthStats.vue'
- // import UserRecords from '@/components/Dashboard/UserRecords.vue'
+ import UserRecords from '@/components/Dashboard/UserRecords/index.vue'
import UserStatsCards from '@/components/Dashboard/UserStartsCards/index.vue'
import { USER_STORE } from '@/store/constants'
import { IAuthUserProfile } from '@/types/user'
@@ -34,7 +34,7 @@
Timeline,
UserCalendar,
UserMonthStats,
- // UserRecords,
+ UserRecords,
UserStatsCards,
},
setup() {
diff --git a/fittrackee_client/tests/unit/utils/dates.spec.ts b/fittrackee_client/tests/unit/utils/dates.spec.ts
index 114cb13d..706c091d 100644
--- a/fittrackee_client/tests/unit/utils/dates.spec.ts
+++ b/fittrackee_client/tests/unit/utils/dates.spec.ts
@@ -1,6 +1,11 @@
import { assert, expect } from 'chai'
-import { getCalendarStartAndEnd, incrementDate, startDate } from '@/utils/dates'
+import {
+ getCalendarStartAndEnd,
+ incrementDate,
+ startDate,
+ formatWorkoutDate,
+} from '@/utils/dates'
describe('startDate (week starting Sunday)', () => {
const testsParams = [
@@ -155,3 +160,68 @@ describe('getCalendarStartAndEnd', () => {
})
)
})
+
+describe('formatWorkoutDate', () => {
+ const testsParams = [
+ {
+ description: 'returns date and time with default format',
+ inputParams: {
+ date: new Date('August 21, 2021 20:00:00'),
+ dateFormat: null,
+ timeFormat: null,
+ },
+ expected: {
+ workout_date: '2021/08/21',
+ workout_time: '20:00',
+ },
+ },
+ {
+ description: 'returns date and time with provided date format',
+ inputParams: {
+ date: new Date('August 21, 2021 20:00:00'),
+ dateFormat: 'dd MM yyyy',
+ timeFormat: null,
+ },
+ expected: {
+ workout_date: '21 08 2021',
+ workout_time: '20:00',
+ },
+ },
+ {
+ description: 'returns date and time with provided time format',
+ inputParams: {
+ date: new Date('August 21, 2021 20:00:00'),
+ dateFormat: null,
+ timeFormat: 'HH:mm:ss',
+ },
+ expected: {
+ workout_date: '2021/08/21',
+ workout_time: '20:00:00',
+ },
+ },
+ {
+ description: 'returns date and time with provided date and time formats',
+ inputParams: {
+ date: new Date('August 21, 2021 20:00:00'),
+ dateFormat: 'dd-MM-yyyy',
+ timeFormat: 'HH:mm:ss',
+ },
+ expected: {
+ workout_date: '21-08-2021',
+ workout_time: '20:00:00',
+ },
+ },
+ ]
+ testsParams.map((testParams) => {
+ it(testParams.description, () => {
+ assert.deepEqual(
+ formatWorkoutDate(
+ testParams.inputParams.date,
+ testParams.inputParams.dateFormat,
+ testParams.inputParams.timeFormat
+ ),
+ testParams.expected
+ )
+ })
+ })
+})
diff --git a/fittrackee_client/tests/unit/utils/records.spec.ts b/fittrackee_client/tests/unit/utils/records.spec.ts
new file mode 100644
index 00000000..24f44670
--- /dev/null
+++ b/fittrackee_client/tests/unit/utils/records.spec.ts
@@ -0,0 +1,256 @@
+import { assert, expect } from 'chai'
+
+import { sports } from './constants'
+
+import { formatRecord, getRecordsBySports } from '@/utils/records'
+
+describe('formatRecord', () => {
+ const testsParams = [
+ {
+ description: "return formatted record for 'Average speed'",
+ inputParams: {
+ record: {
+ id: 9,
+ record_type: 'AS',
+ sport_id: 1,
+ user: 'admin',
+ value: 18,
+ workout_date: 'Sun, 07 Jul 2019 08:00:00 GMT',
+ workout_id: 'hvYBqYBRa7wwXpaStWR4V2',
+ },
+ timezone: 'Europe/Paris',
+ },
+ expected: {
+ id: 9,
+ record_type: 'AS',
+ value: '18 km/h',
+ workout_date: '2019/07/07',
+ workout_id: 'hvYBqYBRa7wwXpaStWR4V2',
+ },
+ },
+ {
+ description: "return formatted record for 'Farest distance'",
+ inputParams: {
+ record: {
+ id: 10,
+ record_type: 'FD',
+ sport_id: 1,
+ user: 'admin',
+ value: 18,
+ workout_date: 'Sun, 07 Jul 2019 22:00:00 GMT',
+ workout_id: 'hvYBqYBRa7wwXpaStWR4V2',
+ },
+ timezone: 'Europe/Paris',
+ },
+ expected: {
+ id: 10,
+ record_type: 'FD',
+ value: '18 km',
+ workout_date: '2019/07/08',
+ workout_id: 'hvYBqYBRa7wwXpaStWR4V2',
+ },
+ },
+ {
+ description: "return formatted record for 'Longest duration'",
+ inputParams: {
+ record: {
+ id: 11,
+ record_type: 'LD',
+ sport_id: 1,
+ user: 'admin',
+ value: '1:01:00',
+ workout_date: 'Sun, 07 Jul 2019 08:00:00 GMT',
+ workout_id: 'hvYBqYBRa7wwXpaStWR4V2',
+ },
+ timezone: 'Europe/Paris',
+ },
+ expected: {
+ id: 11,
+ record_type: 'LD',
+ value: '1:01:00',
+ workout_date: '2019/07/07',
+ workout_id: 'hvYBqYBRa7wwXpaStWR4V2',
+ },
+ },
+ {
+ description: "return formatted record for 'Max. speed'",
+ inputParams: {
+ record: {
+ id: 12,
+ record_type: 'MS',
+ sport_id: 1,
+ user: 'admin',
+ value: 18,
+ workout_date: 'Sun, 07 Jul 2019 22:00:00 GMT',
+ workout_id: 'hvYBqYBRa7wwXpaStWR4V2',
+ },
+ timezone: 'Europe/Paris',
+ },
+ expected: {
+ id: 12,
+ record_type: 'MS',
+ value: '18 km/h',
+ workout_date: '2019/07/08',
+ workout_id: 'hvYBqYBRa7wwXpaStWR4V2',
+ },
+ },
+ ]
+ testsParams.map((testParams) => {
+ it(testParams.description, () => {
+ assert.deepEqual(
+ formatRecord(
+ testParams.inputParams.record,
+ testParams.inputParams.timezone
+ ),
+ testParams.expected
+ )
+ })
+ })
+})
+
+describe('formatRecord (invalid record type)', () => {
+ it('it throws an error if record type is invalid', () => {
+ expect(() =>
+ formatRecord(
+ {
+ id: 12,
+ record_type: 'M',
+ sport_id: 1,
+ user: 'admin',
+ value: 18,
+ workout_date: 'Sun, 07 Jul 2019 22:00:00 GMT',
+ workout_id: 'hvYBqYBRa7wwXpaStWR4V2',
+ },
+ 'Europe/Paris'
+ )
+ ).to.throw(
+ 'Invalid record type, expected: "AS", "FD", "LD", "MD", got: "M"'
+ )
+ })
+})
+
+describe('getRecordsBySports', () => {
+ const testsParams = [
+ {
+ description: 'returns empty object if no records',
+ input: {
+ records: [],
+ tz: 'Europe/Paris',
+ },
+ expected: {},
+ },
+ {
+ description: 'returns record grouped by Sport',
+ input: {
+ records: [
+ {
+ id: 9,
+ record_type: 'AS',
+ sport_id: 1,
+ user: 'admin',
+ value: 18,
+ workout_date: 'Sun, 07 Jul 2019 08:00:00 GMT',
+ workout_id: 'hvYBqYBRa7wwXpaStWR4V2',
+ },
+ ],
+ tz: 'Europe/Paris',
+ },
+ expected: {
+ 'Cycling (Sport)': {
+ img: '/img/sports/cycling-sport.png',
+ records: [
+ {
+ id: 9,
+ record_type: 'AS',
+ value: '18 km/h',
+ workout_date: '2019/07/07',
+ workout_id: 'hvYBqYBRa7wwXpaStWR4V2',
+ },
+ ],
+ },
+ },
+ },
+ {
+ description: 'returns record grouped by Sport',
+ input: {
+ records: [
+ {
+ id: 9,
+ record_type: 'AS',
+ sport_id: 1,
+ user: 'admin',
+ value: 18,
+ workout_date: 'Sun, 07 Jul 2019 08:00:00 GMT',
+ workout_id: 'hvYBqYBRa7wwXpaStWR4V2',
+ },
+ {
+ id: 10,
+ record_type: 'FD',
+ sport_id: 2,
+ user: 'admin',
+ value: 18,
+ workout_date: 'Sun, 07 Jul 2019 22:00:00 GMT',
+ workout_id: 'n6JcLPQt3QtZWFfiSnYm4C',
+ },
+ {
+ id: 12,
+ record_type: 'MS',
+ sport_id: 1,
+ user: 'admin',
+ value: 18,
+ workout_date: 'Sun, 07 Jul 2019 08:00:00 GMT',
+ workout_id: 'hvYBqYBRa7wwXpaStWR4V2',
+ },
+ ],
+ tz: 'Europe/Paris',
+ },
+ expected: {
+ 'Cycling (Sport)': {
+ img: '/img/sports/cycling-sport.png',
+ records: [
+ {
+ id: 9,
+ record_type: 'AS',
+ value: '18 km/h',
+ workout_date: '2019/07/07',
+ workout_id: 'hvYBqYBRa7wwXpaStWR4V2',
+ },
+ {
+ id: 12,
+ record_type: 'MS',
+ value: '18 km/h',
+ workout_date: '2019/07/07',
+ workout_id: 'hvYBqYBRa7wwXpaStWR4V2',
+ },
+ ],
+ },
+ 'Cycling (Transport)': {
+ img: '/img/sports/cycling-transport.png',
+ records: [
+ {
+ id: 10,
+ record_type: 'FD',
+ value: '18 km',
+ workout_date: '2019/07/08',
+ workout_id: 'n6JcLPQt3QtZWFfiSnYm4C',
+ },
+ ],
+ },
+ },
+ },
+ ]
+ testsParams.map((testParams) =>
+ it(testParams.description, () => {
+ assert.deepEqual(
+ getRecordsBySports(
+ testParams.input.records,
+ sports,
+ testParams.input.tz
+ ),
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-ignore
+ testParams.expected
+ )
+ })
+ )
+})
diff --git a/fittrackee_client/tests/unit/utils/sports.spec.ts b/fittrackee_client/tests/unit/utils/sports.spec.ts
new file mode 100644
index 00000000..b3dfbaaf
--- /dev/null
+++ b/fittrackee_client/tests/unit/utils/sports.spec.ts
@@ -0,0 +1,134 @@
+import { assert } from 'chai'
+
+import { sports } from './constants'
+
+import createI18n from '@/i18n'
+import { translateSports } from '@/utils/sports'
+
+const { t, locale } = createI18n.global
+
+describe('sortSports', () => {
+ const testsParams = [
+ {
+ description: "returns sorted all translated sports (with 'en' locale)",
+ inputParams: {
+ sports,
+ locale: 'en',
+ onlyActive: false,
+ },
+ expected: sports,
+ },
+ {
+ description:
+ "returns sorted only active translated sports (with 'en' locales)",
+ inputParams: {
+ sports,
+ locale: 'en',
+ onlyActive: true,
+ },
+ expected: [
+ {
+ has_workouts: false,
+ id: 1,
+ img: '/img/sports/cycling-sport.png',
+ is_active: true,
+ label: 'Cycling (Sport)',
+ },
+ {
+ has_workouts: true,
+ id: 3,
+ img: '/img/sports/hiking.png',
+ is_active: true,
+ label: 'Hiking',
+ },
+ ],
+ },
+ {
+ description: "returns empty array (with 'en' locale)",
+ inputParams: {
+ sports: [],
+ locale: 'en',
+ onlyActive: false,
+ },
+ expected: [],
+ },
+ {
+ description: "returns sorted all translated sports (with 'fr' locale)",
+ inputParams: {
+ sports,
+ locale: 'fr',
+ onlyActive: false,
+ },
+ expected: [
+ {
+ has_workouts: true,
+ id: 3,
+ img: '/img/sports/hiking.png',
+ is_active: true,
+ label: 'Randonnée',
+ },
+ {
+ has_workouts: false,
+ id: 1,
+ img: '/img/sports/cycling-sport.png',
+ is_active: true,
+ label: 'Vélo (Sport)',
+ },
+ {
+ has_workouts: false,
+ id: 2,
+ img: '/img/sports/cycling-transport.png',
+ is_active: false,
+ label: 'Vélo (Transport)',
+ },
+ ],
+ },
+ {
+ description:
+ "returns sorted only active translated sports (with 'fr' locales)",
+ inputParams: {
+ sports,
+ locale: 'fr',
+ onlyActive: true,
+ },
+ expected: [
+ {
+ has_workouts: true,
+ id: 3,
+ img: '/img/sports/hiking.png',
+ is_active: true,
+ label: 'Randonnée',
+ },
+ {
+ has_workouts: false,
+ id: 1,
+ img: '/img/sports/cycling-sport.png',
+ is_active: true,
+ label: 'Vélo (Sport)',
+ },
+ ],
+ },
+ {
+ description: "returns empty array (with 'fr' locale)",
+ inputParams: {
+ sports: [],
+ locale: 'fr',
+ onlyActive: false,
+ },
+ expected: [],
+ },
+ ]
+ testsParams.map((testParams) => {
+ it(testParams.description, () => {
+ locale.value = testParams.inputParams.locale
+ assert.deepEqual(
+ translateSports(
+ testParams.inputParams.sports,
+ t,
+ testParams.inputParams.onlyActive
+ ),
+ testParams.expected
+ )
+ })
+ })
+})