From e44ebc2a196672703ceaa6080819f53e8bef056d Mon Sep 17 00:00:00 2001
From: Yoan VALLET <ext.sopra.yvallet@grandlyon.com>
Date: Wed, 2 Dec 2020 01:34:36 +0100
Subject: [PATCH] feat: add progress and boss launching

---
 src/components/Season/SeasonCard.tsx          |  2 +-
 src/components/Season/SeasonCardBoss.tsx      |  2 +-
 src/components/Season/SeasonCardDone.tsx      |  2 +-
 src/components/Season/SeasonCardLocked.tsx    |  2 +-
 src/components/Season/SeasonCardOnGoing.tsx   | 38 +++++++++-
 src/components/Season/SeasonCardUnlocked.tsx  |  4 +-
 src/components/Season/SeasonView.tsx          |  2 +-
 src/components/Season/season.scss             | 69 -------------------
 src/components/Season/seasonCard.scss         | 23 +++++++
 src/components/Season/seasonCardBoss.scss     |  2 +
 src/components/Season/seasonCardDone.scss     |  2 +
 src/components/Season/seasonCardLocked.scss   |  2 +
 src/components/Season/seasonCardOnGoing.scss  |  2 +
 src/components/Season/seasonCardUnlocked.scss |  2 +
 src/components/Season/seasonView.scss         | 49 +++++++++++++
 src/db/seasonEntity.json                      |  6 +-
 src/enum/updateUserSeason.enum.ts             |  8 +--
 src/services/boss.service.ts                  | 15 ++--
 src/services/season.service.ts                | 35 +++++++---
 19 files changed, 166 insertions(+), 101 deletions(-)
 delete mode 100644 src/components/Season/season.scss
 create mode 100644 src/components/Season/seasonCard.scss
 create mode 100644 src/components/Season/seasonCardBoss.scss
 create mode 100644 src/components/Season/seasonCardDone.scss
 create mode 100644 src/components/Season/seasonCardLocked.scss
 create mode 100644 src/components/Season/seasonCardOnGoing.scss
 create mode 100644 src/components/Season/seasonCardUnlocked.scss
 create mode 100644 src/components/Season/seasonView.scss

diff --git a/src/components/Season/SeasonCard.tsx b/src/components/Season/SeasonCard.tsx
index a989d1711..a7b33712a 100644
--- a/src/components/Season/SeasonCard.tsx
+++ b/src/components/Season/SeasonCard.tsx
@@ -6,7 +6,7 @@ import SeasonCardDone from './SeasonCardDone'
 import SeasonCardLocked from './SeasonCardLocked'
 import SeasonCardOnGoing from './SeasonCardOnGoing'
 import SeasonCardUnlocked from './SeasonCardUnlocked'
-import './season.scss'
+import './seasonCard.scss'
 
 interface SeasonCardProps {
   userSeason: UserSeason
diff --git a/src/components/Season/SeasonCardBoss.tsx b/src/components/Season/SeasonCardBoss.tsx
index 1be2373ba..0ea3cc766 100644
--- a/src/components/Season/SeasonCardBoss.tsx
+++ b/src/components/Season/SeasonCardBoss.tsx
@@ -1,5 +1,5 @@
 import React from 'react'
-import './season.scss'
+import './seasonCardBoss.scss'
 import { UserSeason } from 'models'
 
 interface SeasonCardBossProps {
diff --git a/src/components/Season/SeasonCardDone.tsx b/src/components/Season/SeasonCardDone.tsx
index 008311b7d..2786a5c3e 100644
--- a/src/components/Season/SeasonCardDone.tsx
+++ b/src/components/Season/SeasonCardDone.tsx
@@ -1,5 +1,5 @@
 import React from 'react'
-import './season.scss'
+import './seasonCardDone.scss'
 import { UserSeason } from 'models'
 
 interface SeasonCardDoneProps {
diff --git a/src/components/Season/SeasonCardLocked.tsx b/src/components/Season/SeasonCardLocked.tsx
index d79453ceb..175549749 100644
--- a/src/components/Season/SeasonCardLocked.tsx
+++ b/src/components/Season/SeasonCardLocked.tsx
@@ -1,5 +1,5 @@
 import React from 'react'
-import './season.scss'
+import './seasonCardLocked.scss'
 import { UserSeason } from 'models'
 
 interface SeasonCardLockedProps {
diff --git a/src/components/Season/SeasonCardOnGoing.tsx b/src/components/Season/SeasonCardOnGoing.tsx
index dd6d345f8..eecd75939 100644
--- a/src/components/Season/SeasonCardOnGoing.tsx
+++ b/src/components/Season/SeasonCardOnGoing.tsx
@@ -1,6 +1,11 @@
-import React from 'react'
-import './season.scss'
+import React, { useCallback } from 'react'
+import { Client, useClient } from 'cozy-client'
+import { useDispatch } from 'react-redux'
+import { updateUserSeasonList } from 'store/season/season.actions'
+import './seasonCardOnGoing.scss'
+import SeasonService from 'services/season.service'
 import { UserSeason } from 'models'
+import { UpdateUserSeason } from 'enum/updateUserSeason.enum'
 
 interface SeasonCardOnGoingProps {
   userSeason: UserSeason
@@ -8,10 +13,39 @@ interface SeasonCardOnGoingProps {
 const SeasonCardOnGoing: React.FC<SeasonCardOnGoingProps> = ({
   userSeason,
 }: SeasonCardOnGoingProps) => {
+  const client: Client = useClient()
+  const dispatch = useDispatch()
+
+  const winStarts = useCallback(async () => {
+    const seasonService = new SeasonService(client)
+    userSeason.progress + 5 >= userSeason.target
+      ? (userSeason.progress = userSeason.target)
+      : (userSeason.progress += 5)
+    const updatedSeason = await seasonService.updateUserSeason(
+      userSeason,
+      UpdateUserSeason.SEASON
+    )
+    dispatch(updateUserSeasonList(updatedSeason))
+  }, [client, dispatch, userSeason])
+
+  const launchBoss = useCallback(async () => {
+    const seasonService = new SeasonService(client)
+    const updatedSeason = await seasonService.updateUserSeason(
+      userSeason,
+      UpdateUserSeason.BOSS_START
+    )
+    dispatch(updateUserSeasonList(updatedSeason))
+  }, [client, dispatch, userSeason])
+
   return (
     <div className="cardContent">
       <p className="title">Saison</p>
       <span className="seasonTitle">{userSeason.title}</span>
+      <button onClick={winStarts}>Gagner 5 étoiles</button>
+      <div>{`${userSeason.progress} / ${userSeason.target} Etoiles`}</div>
+      {userSeason.progress >= userSeason.target ? (
+        <button onClick={launchBoss}>Lancer le boss</button>
+      ) : null}
     </div>
   )
 }
diff --git a/src/components/Season/SeasonCardUnlocked.tsx b/src/components/Season/SeasonCardUnlocked.tsx
index 50642f812..9545d8757 100644
--- a/src/components/Season/SeasonCardUnlocked.tsx
+++ b/src/components/Season/SeasonCardUnlocked.tsx
@@ -1,11 +1,11 @@
 import React, { useCallback } from 'react'
 import { Client, useClient } from 'cozy-client'
 import { useDispatch } from 'react-redux'
-import './season.scss'
+import { updateUserSeasonList } from 'store/season/season.actions'
+import './seasonCardUnlocked.scss'
 import { UserSeason } from 'models'
 import SeasonService from 'services/season.service'
 import StyledButtonValid from 'components/CommonKit/Button/StyledButtonValid'
-import { updateUserSeasonList } from 'store/season/season.actions'
 
 interface SeasonCardUnlockedProps {
   userSeason: UserSeason
diff --git a/src/components/Season/SeasonView.tsx b/src/components/Season/SeasonView.tsx
index 085f29f55..8ce712d30 100644
--- a/src/components/Season/SeasonView.tsx
+++ b/src/components/Season/SeasonView.tsx
@@ -1,5 +1,5 @@
 import React, { useState } from 'react'
-import './season.scss'
+import './seasonView.scss'
 import { useSelector } from 'react-redux'
 import { EcolyoState } from 'store'
 import CozyBar from 'components/Header/CozyBar'
diff --git a/src/components/Season/season.scss b/src/components/Season/season.scss
deleted file mode 100644
index 3a81d3f0d..000000000
--- a/src/components/Season/season.scss
+++ /dev/null
@@ -1,69 +0,0 @@
-@import '../../styles/base/typography';
-
-.seasonSlider {
-  min-height: inherit;
-  margin-top: -2rem;
-  overflow-x: hidden;
-  padding: 2rem;
-  position: relative;
-  max-width: 850px;
-  user-select: none;
-  @media all and (min-width: $width-tablet) {
-    margin: auto;
-    margin-top: 2rem;
-    min-height: 0;
-  }
-
-  .container {
-    min-height: inherit;
-    width: 100%;
-    display: flex;
-    transition: all 300ms ease;
-    .slide {
-      margin: auto;
-      height: 465px;
-      // max-width: 285px;
-      // min-width: 285px;
-      background: linear-gradient(180deg, #323339 0%, #25262b 100%);
-      box-shadow: 0px 4px 16px rgba(0, 0, 0, 0.55);
-      border-radius: 4px;
-      margin-right: 1rem;
-      transition: all 300ms ease;
-      color: white;
-      display: flex;
-      flex-direction: column;
-      transform: scale(0.9);
-
-      &.active {
-        transform: scale(1.08);
-      }
-      .cardContent {
-        margin: auto;
-        .title {
-          font-weight: 400;
-          text-align: center;
-          text-transform: uppercase;
-          font-family: $text-font;
-          font-size: 1rem;
-          margin-bottom: 0;
-        }
-        .seasonTitle {
-          display: block;
-          font-weight: 700;
-          text-align: center;
-          font-family: $text-font;
-          color: $grey-bright;
-          font-size: 1.2rem;
-        }
-      }
-    }
-  }
-}
-.sliderButtons {
-  text-align: center;
-  margin: auto;
-  margin-top: 1.5rem;
-  @media all and (max-width: $width-tablet) {
-    display: none;
-  }
-}
diff --git a/src/components/Season/seasonCard.scss b/src/components/Season/seasonCard.scss
new file mode 100644
index 000000000..a3ccd4e0d
--- /dev/null
+++ b/src/components/Season/seasonCard.scss
@@ -0,0 +1,23 @@
+@import '../../styles/base/typography';
+
+.slide {
+  margin: auto;
+  height: 465px;
+  // max-width: 285px;
+  // min-width: 285px;
+  background: linear-gradient(180deg, #323339 0%, #25262b 100%);
+  box-shadow: 0px 4px 16px rgba(0, 0, 0, 0.55);
+  border-radius: 4px;
+  margin-right: 1rem;
+  transition: all 300ms ease;
+  color: white;
+  display: flex;
+  flex-direction: column;
+  transform: scale(0.9);
+
+  &.active {
+    transform: scale(1.08);
+  }
+  
+}
+
diff --git a/src/components/Season/seasonCardBoss.scss b/src/components/Season/seasonCardBoss.scss
new file mode 100644
index 000000000..e4300007a
--- /dev/null
+++ b/src/components/Season/seasonCardBoss.scss
@@ -0,0 +1,2 @@
+@import '../../styles/base/typography';
+
diff --git a/src/components/Season/seasonCardDone.scss b/src/components/Season/seasonCardDone.scss
new file mode 100644
index 000000000..e4300007a
--- /dev/null
+++ b/src/components/Season/seasonCardDone.scss
@@ -0,0 +1,2 @@
+@import '../../styles/base/typography';
+
diff --git a/src/components/Season/seasonCardLocked.scss b/src/components/Season/seasonCardLocked.scss
new file mode 100644
index 000000000..e4300007a
--- /dev/null
+++ b/src/components/Season/seasonCardLocked.scss
@@ -0,0 +1,2 @@
+@import '../../styles/base/typography';
+
diff --git a/src/components/Season/seasonCardOnGoing.scss b/src/components/Season/seasonCardOnGoing.scss
new file mode 100644
index 000000000..e4300007a
--- /dev/null
+++ b/src/components/Season/seasonCardOnGoing.scss
@@ -0,0 +1,2 @@
+@import '../../styles/base/typography';
+
diff --git a/src/components/Season/seasonCardUnlocked.scss b/src/components/Season/seasonCardUnlocked.scss
new file mode 100644
index 000000000..e4300007a
--- /dev/null
+++ b/src/components/Season/seasonCardUnlocked.scss
@@ -0,0 +1,2 @@
+@import '../../styles/base/typography';
+
diff --git a/src/components/Season/seasonView.scss b/src/components/Season/seasonView.scss
new file mode 100644
index 000000000..44e1cc41f
--- /dev/null
+++ b/src/components/Season/seasonView.scss
@@ -0,0 +1,49 @@
+@import '../../styles/base/typography';
+
+.seasonSlider {
+  min-height: inherit;
+  margin-top: -2rem;
+  overflow-x: hidden;
+  padding: 2rem;
+  position: relative;
+  max-width: 850px;
+  user-select: none;
+  @media all and (min-width: $width-tablet) {
+    margin: auto;
+    margin-top: 2rem;
+    min-height: 0;
+  }
+}
+.container {
+  min-height: inherit;
+  width: 100%;
+  display: flex;
+  transition: all 300ms ease;
+}
+.cardContent {
+  margin: auto;
+  .title {
+    font-weight: 400;
+    text-align: center;
+    text-transform: uppercase;
+    font-family: $text-font;
+    font-size: 1rem;
+    margin-bottom: 0;
+  }
+  .seasonTitle {
+    display: block;
+    font-weight: 700;
+    text-align: center;
+    font-family: $text-font;
+    color: $grey-bright;
+    font-size: 1.2rem;
+  }
+}
+.sliderButtons {
+  text-align: center;
+  margin: auto;
+  margin-top: 1.5rem;
+  @media all and (max-width: $width-tablet) {
+    display: none;
+  }
+}
\ No newline at end of file
diff --git a/src/db/seasonEntity.json b/src/db/seasonEntity.json
index 18ab7aff9..2f755459a 100644
--- a/src/db/seasonEntity.json
+++ b/src/db/seasonEntity.json
@@ -3,7 +3,7 @@
     "_id": "SEASON0001",
     "title": "Nicolas Hublot",
     "description": "foobar",
-    "target": 40,
+    "target": 15,
     "relationships": {
       "boss": {
         "data": { "_id": "BO001", "_type": "com.grandlyon.ecolyo.boss" }
@@ -15,7 +15,7 @@
     "_id": "SEASON0002",
     "title": "Tata",
     "description": "foobar",
-    "target": 40,
+    "target": 15,
     "relationships": {
       "boss": {
         "data": { "_id": "BO002", "_type": "com.grandlyon.ecolyo.boss" }
@@ -27,7 +27,7 @@
     "_id": "SEASON0003",
     "title": "Titi",
     "description": "foobar",
-    "target": 40,
+    "target": 15,
     "relationships": {
       "boss": {
         "data": { "_id": "BO003", "_type": "com.grandlyon.ecolyo.boss" }
diff --git a/src/enum/updateUserSeason.enum.ts b/src/enum/updateUserSeason.enum.ts
index c1b342ade..85d0c8dcf 100644
--- a/src/enum/updateUserSeason.enum.ts
+++ b/src/enum/updateUserSeason.enum.ts
@@ -1,6 +1,6 @@
 export enum UpdateUserSeason {
-  QUIZ = 0,
-  MISSION = 1,
-  BOSS = 2,
-  END = 3,
+  SEASON = 0,
+  BOSS_START = 10,
+  QUIZ = 20,
+  MISSION = 30,
 }
diff --git a/src/services/boss.service.ts b/src/services/boss.service.ts
index 1f84976f3..96cac3ba5 100644
--- a/src/services/boss.service.ts
+++ b/src/services/boss.service.ts
@@ -2,7 +2,7 @@ import { Client, QueryDefinition, QueryResult, Q } from 'cozy-client'
 import { BOSS_DOCTYPE } from 'doctypes/com-grandlyon-ecolyo-boss'
 import { Boss, BossEntity } from 'models/boss.model'
 import { UserBossState } from 'enum/userBoss.enum'
-import { Duration } from 'luxon'
+import { DateTime, Duration } from 'luxon'
 
 export default class BossService {
   private readonly _client: Client
@@ -39,11 +39,14 @@ export default class BossService {
   }
 
   public async startUserBoss(userBoss: Boss): Promise<Boss> {
-    /* 
-
-    */
-
-    return userBoss
+    const updatedUserBoss: Boss = {
+      ...userBoss,
+      state: UserBossState.ONGOING,
+      startDate: DateTime.local(),
+      // TODO add calculation of threshold
+      treshold: 50,
+    }
+    return updatedUserBoss
   }
 
   public formatToUserBoss(boss: BossEntity): Boss {
diff --git a/src/services/season.service.ts b/src/services/season.service.ts
index d11f554d1..56a503da0 100644
--- a/src/services/season.service.ts
+++ b/src/services/season.service.ts
@@ -69,7 +69,6 @@ export default class SeasonService {
     let buildList: UserSeason[] = []
     if (seasonEntityList.length > 0 && userSeasonList.length === 0) {
       seasonEntityList.forEach(async season => {
-        console.log(season)
         const bossEntityRelation: Relation = getRelationship(season, 'boss')
         const boss: Boss = bossService.getBossfromBossEntities(
           bossEntityList || [],
@@ -145,7 +144,9 @@ export default class SeasonService {
     userSeason.startDate = DateTime.local()
     userSeason.success = UserSeasonSuccess.ONGOING
     try {
-      const { data: updatedUserSeason } = await this._client.create(
+      const {
+        data: updatedUserSeason,
+      }: QueryResult<UserSeason> = await this._client.create(
         USERSEASON_DOCTYPE,
         userSeason
       )
@@ -160,14 +161,28 @@ export default class SeasonService {
     userSeason: UserSeason,
     flag: UpdateUserSeason
   ): Promise<UserSeason> {
-    /* 
-    Update Quiz
-    Update Mission
-    Update Boss
-    Update Season (END of season)
-   */
-
-    return userSeason
+    let updatedUserSeason
+    switch (flag) {
+      case UpdateUserSeason.SEASON:
+        updatedUserSeason = userSeason
+        break
+      case UpdateUserSeason.BOSS_START:
+        const bossService = new BossService(this._client)
+        const updatedBoss = await bossService.startUserBoss(userSeason.boss)
+        updatedUserSeason = {
+          ...userSeason,
+          state: UserSeasonState.BOSS,
+          boss: updatedBoss,
+        }
+        break
+      default:
+        updatedUserSeason = userSeason
+        break
+    }
+    const { data }: QueryResult<UserSeason> = await this._client.save(
+      updatedUserSeason
+    )
+    return data
   }
 
   public async isUserSeasonOver(userSeason: UserSeason): Promise<UserSeason> {
-- 
GitLab