From 2f525f1de94a387280433dcfc1f3b73f5b2a56c2 Mon Sep 17 00:00:00 2001
From: Guilhem CARRON <gcarron@grandlyon.com>
Date: Wed, 2 Mar 2022 14:29:11 +0000
Subject: [PATCH] feat(price): Add price managment

---
 dbinit/dbinit.sql                      |   4 +
 dbinit/fluidprices.CSV                 |  84 ++++++++++
 dbinit/init.md                         |  25 +++
 docker-compose.local.yml               |   6 +-
 docker-compose.yml                     |   2 +
 package.json                           |   1 +
 src/assets/icons/down-arrow.png        | Bin 0 -> 6724 bytes
 src/assets/icons/editing.png           | Bin 0 -> 19180 bytes
 src/components/Prices/PriceRow.tsx     |  55 +++++++
 src/components/Prices/PriceSection.tsx | 215 +++++++++++++++++++++++++
 src/components/Prices/Prices.tsx       |  28 ++++
 src/components/Prices/prices.scss      | 119 ++++++++++++++
 src/components/Routes/Routes.tsx       |   2 +
 src/constants/routes.json              |   4 +
 src/enum/fluidTypes.ts                 |   5 +
 src/enum/frequency.enum.ts             |   5 +
 src/models/price.model.ts              |   6 +
 src/services/prices.service.ts         |  36 +++++
 src/styles/config/_typography.scss     |   4 +
 yarn.lock                              |   5 +
 20 files changed, 604 insertions(+), 2 deletions(-)
 create mode 100644 dbinit/dbinit.sql
 create mode 100644 dbinit/fluidprices.CSV
 create mode 100644 dbinit/init.md
 create mode 100644 src/assets/icons/down-arrow.png
 create mode 100644 src/assets/icons/editing.png
 create mode 100644 src/components/Prices/PriceRow.tsx
 create mode 100644 src/components/Prices/PriceSection.tsx
 create mode 100644 src/components/Prices/Prices.tsx
 create mode 100644 src/components/Prices/prices.scss
 create mode 100644 src/enum/fluidTypes.ts
 create mode 100644 src/enum/frequency.enum.ts
 create mode 100644 src/models/price.model.ts
 create mode 100644 src/services/prices.service.ts

diff --git a/dbinit/dbinit.sql b/dbinit/dbinit.sql
new file mode 100644
index 00000000..1070e073
--- /dev/null
+++ b/dbinit/dbinit.sql
@@ -0,0 +1,4 @@
+LOAD DATA LOCAL INFILE '/dbinit/fluidprices.CSV' INTO TABLE prices 
+FIELDS TERMINATED BY ',' 
+LINES TERMINATED BY '\n'
+IGNORE 1 ROWS;
\ No newline at end of file
diff --git a/dbinit/fluidprices.CSV b/dbinit/fluidprices.CSV
new file mode 100644
index 00000000..21670990
--- /dev/null
+++ b/dbinit/fluidprices.CSV
@@ -0,0 +1,84 @@
+fluid_type,price,start_date,end_date,id,created_at,updated_at
+0,0.1256,2012-07-23T00:00:00Z,2013-07-31T23:59:59Z,1,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+0,0.1329,2013-08-01T00:00:00Z,2014-10-31T23:59:59Z,2,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+0,0.1401,2014-01-11T00:00:00Z,2015-07-31T23:59:59Z,3,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+0,0.1437,2015-08-01T00:00:00Z,2016-07-31T23:59:59Z,4,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+0,0.1503,2016-08-01T00:00:00Z,2017-07-31T23:59:59Z,5,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+0,0.1546,2017-08-01T00:00:00Z,2018-01-31T23:59:59Z,6,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+0,0.1555,2018-02-01T00:00:00Z,2018-07-31T23:59:59Z,7,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+0,0.145,2018-08-01T00:00:00Z,2019-05-31T23:59:59Z,8,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+0,0.1531,2019-06-01T00:00:00Z,2019-07-31T23:59:59Z,9,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+0,0.1524,2019-08-01T00:00:00Z,2020-01-31T23:59:59Z,10,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+0,0.1546,2020-02-01T00:00:00Z,2020-07-31T23:59:59Z,11,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+0,0.1557,2020-08-01T00:00:00Z,2021-01-31T23:59:59Z,12,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+0,0.1582,2021-02-01T00:00:00Z,2021-07-31T23:59:59Z,13,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+0,0.1558,2021-08-01T00:00:00Z,2022-01-31T23:59:59Z,14,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+0,0.174,2022-02-01T00:00:00Z,,15,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+1,0.0030735,2012-01-01T00:00:00Z,2012-12-31T23:59:59Z,16,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+1,0.0031483,2013-01-01T00:00:00Z,2013-12-31T23:59:59Z,17,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+1,0.0031381,2014-01-01T00:00:00Z,2014-12-31T23:59:59Z,18,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+1,0.00307,2015-01-01T00:00:00Z,2015-12-31T23:59:59Z,19,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+1,0.0031,2016-01-01T00:00:00Z,2016-12-31T23:59:59Z,20,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+1,0.00311,2017-01-01T00:00:00Z,2017-12-31T23:59:59Z,21,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+1,0.00313,2018-01-01T00:00:00Z,2018-12-31T23:59:59Z,22,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+1,0.00313,2019-01-01T00:00:00Z,2019-12-31T23:59:59Z,23,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+1,0.00315,2020-01-01T00:00:00Z,2020-12-31T23:59:59Z,24,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+1,0.00319,2021-01-01T00:00:00Z,,25,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0919,2017-01-01T00:00:00Z,2017-01-31T23:59:59Z,26,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0915,2017-02-01T00:00:00Z,2017-02-28T23:59:59Z,27,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0932,2017-03-01T00:00:00Z,2017-03-31T23:59:59Z,28,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0927,2017-04-01T00:00:00Z,2017-04-30T23:59:59Z,29,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0906,2017-05-01T00:00:00Z,2017-05-31T23:59:59Z,30,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0906,2017-06-01T00:00:00Z,2017-06-30T23:59:59Z,31,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0788,2017-07-01T00:00:00Z,2017-07-31T23:59:59Z,32,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0783,2017-08-01T00:00:00Z,2017-08-31T23:59:59Z,33,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0783,2017-09-01T00:00:00Z,2017-09-30T23:59:59Z,34,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0791,2017-10-01T00:00:00Z,2017-10-31T23:59:59Z,35,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0806,2017-11-01T00:00:00Z,2017-11-30T23:59:59Z,36,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0812,2017-12-01T00:00:00Z,2017-12-31T23:59:59Z,37,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0857,2018-01-01T00:00:00Z,2018-01-31T23:59:59Z,38,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0866,2018-02-01T00:00:00Z,2018-02-28T23:59:59Z,39,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0847,2018-03-01T00:00:00Z,2018-03-31T23:59:59Z,40,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0839,2018-04-01T00:00:00Z,2018-04-30T23:59:59Z,41,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0842,2018-05-01T00:00:00Z,2018-05-31T23:59:59Z,42,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0855,2018-06-01T00:00:00Z,2018-06-30T23:59:59Z,43,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0959,2018-07-01T00:00:00Z,2018-07-31T23:59:59Z,44,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0961,2018-08-01T00:00:00Z,2018-08-31T23:59:59Z,45,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0967,2018-09-01T00:00:00Z,2018-09-30T23:59:59Z,46,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0989,2018-10-01T00:00:00Z,2018-10-31T23:59:59Z,47,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.1031,2018-11-01T00:00:00Z,2018-11-30T23:59:59Z,48,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.1013,2018-12-01T00:00:00Z,2018-12-31T23:59:59Z,49,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0999,2019-01-01T00:00:00Z,2019-01-31T23:59:59Z,50,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0993,2019-02-01T00:00:00Z,2019-02-28T23:59:59Z,51,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0993,2019-03-01T00:00:00Z,2019-03-31T23:59:59Z,52,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0977,2019-04-01T00:00:00Z,2019-04-30T23:59:59Z,53,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0973,2019-05-01T00:00:00Z,2019-05-31T23:59:59Z,54,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0969,2019-06-01T00:00:00Z,2019-06-30T23:59:59Z,55,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0795,2019-07-01T00:00:00Z,2019-07-31T23:59:59Z,56,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0791,2019-08-01T00:00:00Z,2019-08-31T23:59:59Z,57,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0785,2019-09-01T00:00:00Z,2019-09-30T23:59:59Z,58,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.077,2019-10-01T00:00:00Z,2019-10-31T23:59:59Z,59,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0789,2019-11-01T00:00:00Z,2019-11-30T23:59:59Z,60,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0793,2019-12-01T00:00:00Z,2019-12-31T23:59:59Z,61,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0787,2020-01-01T00:00:00Z,2020-01-31T23:59:59Z,62,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0765,2020-02-01T00:00:00Z,2020-02-29T23:59:59Z,70,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0736,2020-03-01T00:00:00Z,2020-03-31T23:59:59Z,71,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.071,2020-04-01T00:00:00Z,2020-04-30T23:59:59Z,72,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0703,2020-05-01T00:00:00Z,2020-05-31T23:59:59Z,73,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0687,2020-06-01T00:00:00Z,2020-06-30T23:59:59Z,74,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0698,2020-07-01T00:00:00Z,2020-07-31T23:59:59Z,75,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0705,2020-08-01T00:00:00Z,2020-08-31T23:59:59Z,76,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0709,2020-09-01T00:00:00Z,2020-09-30T23:59:59Z,77,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0735,2020-10-01T00:00:00Z,2020-10-31T23:59:59Z,78,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0745,2020-11-01T00:00:00Z,2020-11-30T23:59:59Z,79,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0759,2020-12-01T00:00:00Z,2020-12-31T23:59:59Z,80,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.076,2021-01-01T00:00:00Z,2021-01-31T23:59:59Z,81,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0782,2021-02-01T00:00:00Z,2021-02-28T23:59:59Z,82,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0818,2021-03-01T00:00:00Z,2021-03-31T23:59:59Z,83,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.079,2021-04-01T00:00:00Z,2021-04-30T23:59:59Z,84,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0797,2021-05-01T00:00:00Z,2021-05-31T23:59:59Z,85,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0826,2021-06-01T00:00:00Z,2021-06-30T23:59:59Z,86,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0895,2021-07-01T00:00:00Z,2021-07-31T23:59:59Z,87,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.0934,2021-08-01T00:00:00Z,2021-08-31T23:59:59Z,88,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.1002,2021-09-01T00:00:00Z,2021-09-30T23:59:59Z,89,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
+2,0.1121,2021-10-01T00:00:00Z,,90,2000-01-01T00:00:00Z,2000-01-01T00:00:00Z
\ No newline at end of file
diff --git a/dbinit/init.md b/dbinit/init.md
new file mode 100644
index 00000000..21120af5
--- /dev/null
+++ b/dbinit/init.md
@@ -0,0 +1,25 @@
+# Init first prices data
+
+## Local
+
+If the script is not working (problem with secure_file_priv variable), use the import in phpMyAdmin:
+
+- Ignore the request for the first line
+- Select format "CVS using LOAD DATA"
+- Choose the right column separator ","
+- Then launch the execution
+
+## Rec/Prod
+
+- Connect to mysql docker container
+
+```
+docker exec -it <container-id> bash
+```
+
+- Open mysql shell
+
+```
+mysql --local-infile=1 -uroot -p backoffice < /dbinit/dbinit.sql
+
+```
diff --git a/docker-compose.local.yml b/docker-compose.local.yml
index 14115d60..76db778a 100644
--- a/docker-compose.local.yml
+++ b/docker-compose.local.yml
@@ -12,8 +12,8 @@ services:
     depends_on:
       - backend
     # For linux users
-    # extra_hosts:
-    #   - 'host.docker.internal:host-gateway'
+    extra_hosts:
+      - 'host.docker.internal:host-gateway'
 
   database-agent:
     image: mysql:5
@@ -27,6 +27,8 @@ services:
       interval: 5s
       timeout: 10s
       retries: 60
+    volumes:
+      - ./dbinit:/dbinit
 
   backend:
     image: registry.forge.grandlyon.com/web-et-numerique/llle_project/backoffice-server:dev
diff --git a/docker-compose.yml b/docker-compose.yml
index 0ef136a4..ca641669 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -29,6 +29,8 @@ services:
       interval: 5s
       timeout: 10s
       retries: 60
+    volumes:
+      - ./dbinit:/dbinit
 
   backend:
     image: registry.forge.grandlyon.com/web-et-numerique/llle_project/backoffice-server:dev
diff --git a/package.json b/package.json
index 5dc3567c..e20fdf70 100644
--- a/package.json
+++ b/package.json
@@ -60,6 +60,7 @@
     "@types/html-to-draftjs": "^1.4.0",
     "@types/react-draft-wysiwyg": "^1.13.3",
     "axios": "^0.21.1",
+    "dayjs": "^1.10.7",
     "draft-js": "^0.11.7",
     "draft-js-export-html": "^1.4.1",
     "html-to-draftjs": "^1.5.0",
diff --git a/src/assets/icons/down-arrow.png b/src/assets/icons/down-arrow.png
new file mode 100644
index 0000000000000000000000000000000000000000..9bb76b55bb71faa4986fca57ca4974b39a76e836
GIT binary patch
literal 6724
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

literal 0
HcmV?d00001

diff --git a/src/assets/icons/editing.png b/src/assets/icons/editing.png
new file mode 100644
index 0000000000000000000000000000000000000000..5866258a45d4ca656122356afc42bcf6b35c4ae0
GIT binary patch
literal 19180
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

literal 0
HcmV?d00001

diff --git a/src/components/Prices/PriceRow.tsx b/src/components/Prices/PriceRow.tsx
new file mode 100644
index 00000000..d3e5b0d0
--- /dev/null
+++ b/src/components/Prices/PriceRow.tsx
@@ -0,0 +1,55 @@
+import React from 'react'
+import { IPrice } from '../../models/price.model'
+import editing from '../../assets/icons/editing.png'
+
+interface PriceSectionProps {
+  getDate: (date: string) => string
+  setPriceToSave: React.Dispatch<React.SetStateAction<IPrice>>
+  priceToSave: IPrice
+  price: IPrice
+  prices: IPrice[]
+  index: number
+  isNextPrice?: boolean
+}
+
+const PriceRow: React.FC<PriceSectionProps> = ({
+  getDate,
+  setPriceToSave,
+  priceToSave,
+  price,
+  prices,
+  index,
+  isNextPrice,
+}: PriceSectionProps) => {
+  const editableLimit: number = 3
+
+  return (
+    <>
+      <li
+        className={
+          priceToSave.startDate === price.startDate
+            ? 'flex-bloc price-selected'
+            : 'flex-bloc'
+        }
+      >
+        <div className="prix">
+          {price.price === '' ? '----' : price.price} €
+        </div>
+        <p>
+          à partir de :{' '}
+          <span className="capital">{getDate(price.startDate)}</span>
+        </p>
+        {index < editableLimit - 1 && (
+          <img
+            src={editing}
+            onClick={() => setPriceToSave(isNextPrice ? price : prices[index])}
+            alt="edit-icon"
+          />
+        )}
+      </li>
+      <hr></hr>
+    </>
+  )
+}
+
+export default PriceRow
diff --git a/src/components/Prices/PriceSection.tsx b/src/components/Prices/PriceSection.tsx
new file mode 100644
index 00000000..20e70cb9
--- /dev/null
+++ b/src/components/Prices/PriceSection.tsx
@@ -0,0 +1,215 @@
+import React, { useCallback, useContext, useEffect, useState } from 'react'
+import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css'
+import { FluidType } from '../../enum/fluidTypes'
+import { FrequencyInMonth } from '../../enum/frequency.enum'
+import { UserContext, UserContextProps } from '../../hooks/userContext'
+import { IPrice } from '../../models/price.model'
+import { PricesService } from '../../services/prices.service'
+import arrowDown from '../../assets/icons/down-arrow.png'
+
+import Loader from '../Loader/Loader'
+import './prices.scss'
+import dayjs from 'dayjs'
+import utc from 'dayjs/plugin/utc'
+import timezone from 'dayjs/plugin/timezone'
+import PriceRow from './PriceRow'
+dayjs.extend(utc)
+dayjs.extend(timezone)
+
+interface PriceSectionProps {
+  fluid: FluidType
+  frequency: FrequencyInMonth
+}
+
+const PriceSection: React.FC<PriceSectionProps> = ({
+  fluid,
+  frequency,
+}: PriceSectionProps) => {
+  const [prices, setPrices] = useState<IPrice[]>([])
+  const [nextPrice, setNextPrice] = useState<IPrice>()
+  const [isLoading, setIsLoading] = useState<boolean>(false)
+  const [refreshData, setRefreshData] = useState<boolean>(false)
+  const [showHistory, setShowHistory] = useState<boolean>(false)
+  const [showFullList, setShowFullList] = useState<boolean>(false)
+  const [priceToSave, setPriceToSave] = useState<IPrice>({
+    fluidType: fluid,
+    price: '',
+    startDate: '',
+    endDate: null,
+  })
+  const { user }: Partial<UserContextProps> = useContext(UserContext)
+  const maxPerList: number = 8
+
+  const handlePriceSelection = useCallback((val: string) => {
+    if (val === '') val = '0'
+    val = val.replace(/,/g, '.')
+    val = val.replace(/([^0-9.]+)/, '')
+    setPriceToSave((prev) => {
+      return { ...prev, price: val }
+    })
+  }, [])
+
+  const savePrice = useCallback(async () => {
+    if (
+      priceToSave &&
+      user &&
+      priceToSave.price !== '0' &&
+      priceToSave.price !== ''
+    ) {
+      const priceService = new PricesService()
+      const formattedPrice = {
+        ...priceToSave,
+        price: parseFloat(priceToSave.price as string),
+      }
+      await priceService.savePrice(formattedPrice, user.xsrftoken)
+      setRefreshData(true)
+    }
+  }, [priceToSave, user])
+
+  const toggleHistory = useCallback(() => {
+    setShowHistory((prev) => !prev)
+  }, [])
+
+  const getDate = useCallback((isoString: string): string => {
+    const date = new Date(isoString)
+    const month = date.toLocaleString('fr', { month: 'long' })
+    const year = date.toLocaleString('fr', { year: 'numeric' })
+    return `${month} ${year}`
+  }, [])
+
+  const toggleFullList = useCallback(() => {
+    setShowFullList((prev) => !prev)
+  }, [])
+
+  useEffect(() => {
+    let subscribed = true
+    setIsLoading(true)
+    async function getPrices() {
+      const priceService = new PricesService()
+      const pricesByFluid = await priceService.getPricesByFluid(fluid)
+      if (pricesByFluid.length) {
+        const nextPriceToCreate: IPrice = {
+          fluidType: fluid,
+          price: '',
+          startDate: '',
+          endDate: null,
+        }
+        // Set the correct for the next price to create
+        const date: string = dayjs(pricesByFluid[0].startDate)
+          .utc(true)
+          .tz('Europe/Paris')
+          .add(frequency, 'month')
+          .startOf('day')
+          .format('YYYY-MM-DDTHH:mm:ss[Z]')
+
+        nextPriceToCreate.startDate = date
+        if (subscribed) {
+          setPrices(pricesByFluid)
+          setPriceToSave(nextPriceToCreate)
+          setNextPrice(nextPriceToCreate)
+        }
+        setIsLoading(false)
+      }
+    }
+    getPrices()
+
+    return () => {
+      subscribed = false
+      setRefreshData(false)
+    }
+  }, [refreshData, frequency, fluid])
+
+  if (isLoading) return <Loader></Loader>
+  if (!prices.length) return <section> Aucun prix trouvé</section>
+  return (
+    <section>
+      <h2>
+        {fluid === FluidType.ELECTRICITY && 'Electricité'}
+        {fluid === FluidType.WATER && 'Eau'}
+        {fluid === FluidType.GAS && 'Gaz'}
+      </h2>
+      <hr className="price-separator" />
+      <div className="flex-bloc">
+        <p>Nouveau prix : </p>
+        <input
+          className="input-dark price-select"
+          type="text"
+          value={priceToSave.price.toString()}
+          onChange={(e) => handlePriceSelection(e.target.value)}
+          placeholder={priceToSave.price === '' ? 'Saisir le nouveau prix' : ''}
+        />
+        <span className="euro">€</span>
+
+        <div className="flex-bloc startDate">
+          <p>A partir de : </p>
+          <p className="date">
+            <span className="capital">{getDate(priceToSave.startDate)}</span>
+          </p>
+        </div>
+      </div>
+      <button
+        className="btnValid"
+        onClick={savePrice}
+        disabled={priceToSave.price === '0' || priceToSave.price === ''}
+      >
+        Sauvegarder
+      </button>
+      <div className="history">
+        <button onClick={toggleHistory} className={showHistory ? 'active' : ''}>
+          <span>Voir l'historique</span>
+          <img
+            src={arrowDown}
+            className={showHistory ? 'icon-active' : ''}
+            alt="arrow-icon"
+          />
+        </button>
+        {showHistory && (
+          <ul className={showHistory ? 'active' : ''}>
+            {nextPrice && (
+              <PriceRow
+                getDate={getDate}
+                priceToSave={priceToSave}
+                price={nextPrice}
+                prices={prices}
+                setPriceToSave={setPriceToSave}
+                index={0}
+                isNextPrice={true}
+              />
+            )}
+            {prices.map((price, i) => {
+              return (
+                <div
+                  key={i}
+                  className={
+                    i > maxPerList && !showFullList ? 'price-hidden' : ''
+                  }
+                >
+                  <PriceRow
+                    getDate={getDate}
+                    priceToSave={priceToSave}
+                    price={price}
+                    prices={prices}
+                    setPriceToSave={setPriceToSave}
+                    index={i}
+                  />
+                  {i === maxPerList && !showFullList && (
+                    <button onClick={toggleFullList} className="showButton">
+                      En voir plus
+                    </button>
+                  )}
+                </div>
+              )
+            })}
+            {showFullList && (
+              <button onClick={toggleFullList} className="showButton">
+                En voir moins
+              </button>
+            )}
+          </ul>
+        )}
+      </div>
+    </section>
+  )
+}
+
+export default PriceSection
diff --git a/src/components/Prices/Prices.tsx b/src/components/Prices/Prices.tsx
new file mode 100644
index 00000000..beb1286e
--- /dev/null
+++ b/src/components/Prices/Prices.tsx
@@ -0,0 +1,28 @@
+import React from 'react'
+import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css'
+import { FluidType } from '../../enum/fluidTypes'
+import { FrequencyInMonth } from '../../enum/frequency.enum'
+import './prices.scss'
+import PriceSection from './PriceSection'
+const Prices: React.FC = () => {
+  return (
+    <>
+      <div className="header">
+        <p className="title pagetitle">Prix des fluides</p>
+      </div>
+      <div className="prices">
+        <PriceSection
+          fluid={FluidType.ELECTRICITY}
+          frequency={FrequencyInMonth.ELECTRICITY}
+        />
+        <PriceSection
+          fluid={FluidType.WATER}
+          frequency={FrequencyInMonth.WATER}
+        />
+        <PriceSection fluid={FluidType.GAS} frequency={FrequencyInMonth.GAS} />
+      </div>
+    </>
+  )
+}
+
+export default Prices
diff --git a/src/components/Prices/prices.scss b/src/components/Prices/prices.scss
new file mode 100644
index 00000000..0f0d367b
--- /dev/null
+++ b/src/components/Prices/prices.scss
@@ -0,0 +1,119 @@
+@import '../../styles/config/typography.scss';
+@import '../../styles/config/layout.scss';
+@import '../../styles/config/breakpoints';
+@import '../../styles/config/colors';
+
+.prices {
+  margin-top: $navigator-height;
+  padding: 1rem;
+  .title {
+    margin: 1rem 0;
+  }
+  .capital {
+    text-transform: capitalize;
+  }
+  h2 {
+    margin-bottom: 1rem;
+    color: $gold;
+  }
+  .price-separator {
+    margin: 1rem 0;
+    background: white;
+  }
+  .flex-bloc {
+    display: flex;
+    align-items: center;
+    .price-select {
+      position: relative;
+    }
+    .euro {
+      display: block;
+      margin-left: 0.5rem;
+      font-weight: bold;
+    }
+    .startDate {
+      margin-left: 1rem;
+      .date {
+        margin-left: 0.5rem;
+        color: $gold;
+        font-weight: bold;
+      }
+    }
+  }
+  section {
+    margin-top: 1rem;
+    margin-bottom: 2rem;
+    .history {
+      button {
+        @include baseButton();
+        background: $grey-dark;
+        border: solid 1px $gold;
+        display: flex;
+        align-items: center;
+        &:hover {
+          background: $dark-background;
+          opacity: 0.8;
+        }
+        &.active {
+          border-radius: 5px 5px 0 0;
+        }
+        img {
+          width: 20px;
+          margin-left: 0.5rem;
+        }
+        span {
+          color: $gold;
+        }
+      }
+      ul {
+        transition: all 300ms ease;
+        background: $grey-dark;
+        border: solid 1px $gold;
+        padding: 1rem;
+        .price-hidden {
+          display: none;
+        }
+        li {
+          transition: all 300ms ease;
+          margin: 0.5rem 0;
+          padding: 0.5rem;
+          .prix {
+            transition: all 300ms ease;
+            font-weight: bold;
+            min-width: 120px;
+          }
+          p,
+          p span {
+            transition: all 300ms ease;
+            margin-left: 1rem;
+          }
+          img {
+            cursor: pointer;
+            width: 22px;
+            margin-left: auto;
+            transition: all 300ms ease;
+          }
+        }
+        .price-selected {
+          background: $gold;
+          .prix,
+          p,
+          p span {
+            color: black;
+          }
+        }
+        hr {
+          margin: 0;
+          background: white;
+        }
+        .showButton {
+          text-align: center;
+          color: $gold;
+        }
+      }
+      .icon-active {
+        transform: rotate(180deg);
+      }
+    }
+  }
+}
diff --git a/src/components/Routes/Routes.tsx b/src/components/Routes/Routes.tsx
index a5c1b43a..5a56426c 100644
--- a/src/components/Routes/Routes.tsx
+++ b/src/components/Routes/Routes.tsx
@@ -3,6 +3,7 @@ import { Redirect, Route, Switch } from 'react-router-dom'
 import { UserContext } from '../../hooks/userContext'
 import Editing from '../Editing/Editing'
 import Login from '../Login/Login'
+import Prices from '../Prices/Prices'
 import Settings from '../Settings/Settings'
 import PrivateRoute from './PrivateRoute'
 
@@ -14,6 +15,7 @@ const Routes: React.FC = () => {
       {user && <Redirect path="/login" to="/editing" />}
       <Route path="/login" component={Login} />
       <PrivateRoute path="/editing" component={Editing} exact />
+      <PrivateRoute path="/prices" component={Prices} exact />
       <PrivateRoute path="/settings" component={Settings} exact />
       <Redirect path="*" to="/editing" />
     </Switch>
diff --git a/src/constants/routes.json b/src/constants/routes.json
index 21414496..c0f67b83 100644
--- a/src/constants/routes.json
+++ b/src/constants/routes.json
@@ -3,6 +3,10 @@
     "label": "Edition",
     "path": "/editing"
   },
+  {
+    "label": "Prix",
+    "path": "/prices"
+  },
   {
     "label": "Paramètres",
     "path": "/settings"
diff --git a/src/enum/fluidTypes.ts b/src/enum/fluidTypes.ts
new file mode 100644
index 00000000..62e46bca
--- /dev/null
+++ b/src/enum/fluidTypes.ts
@@ -0,0 +1,5 @@
+export enum FluidType {
+  ELECTRICITY = 0,
+  WATER = 1,
+  GAS = 2,
+}
diff --git a/src/enum/frequency.enum.ts b/src/enum/frequency.enum.ts
new file mode 100644
index 00000000..211ae180
--- /dev/null
+++ b/src/enum/frequency.enum.ts
@@ -0,0 +1,5 @@
+export enum FrequencyInMonth {
+  ELECTRICITY = 6,
+  WATER = 12,
+  GAS = 1,
+}
diff --git a/src/models/price.model.ts b/src/models/price.model.ts
new file mode 100644
index 00000000..fb1e52d1
--- /dev/null
+++ b/src/models/price.model.ts
@@ -0,0 +1,6 @@
+export interface IPrice {
+  fluidType: number
+  price: number | string
+  startDate: string
+  endDate: string | null
+}
diff --git a/src/services/prices.service.ts b/src/services/prices.service.ts
new file mode 100644
index 00000000..723b1360
--- /dev/null
+++ b/src/services/prices.service.ts
@@ -0,0 +1,36 @@
+import axios from 'axios'
+import { toast } from 'react-toastify'
+import { IPrice } from '../models/price.model'
+export class PricesService {
+  /**
+   * Save the partnersInfo
+   * @param price
+   * @param token
+   */
+  public savePrice = async (price: IPrice, token: string): Promise<void> => {
+    try {
+      await axios.put(`/api/admin/prices`, price, {
+        headers: {
+          'XSRF-TOKEN': token,
+        },
+      })
+      toast.success('Price succesfully saved !')
+    } catch (e) {
+      toast.error('Failed to save price')
+      console.error(e)
+    }
+  }
+
+  /**
+   * Gets the prices by fluid
+   */
+  public getPricesByFluid = async (fluidType: number): Promise<IPrice[]> => {
+    try {
+      const { data } = await axios.get(`/api/common/prices/${fluidType}`)
+      return data
+    } catch (e) {
+      console.error('error', e)
+      return []
+    }
+  }
+}
diff --git a/src/styles/config/_typography.scss b/src/styles/config/_typography.scss
index 380fea21..55178241 100644
--- a/src/styles/config/_typography.scss
+++ b/src/styles/config/_typography.scss
@@ -46,6 +46,10 @@ $main-spacing: 4px;
   &:hover {
     background-color: #b89318;
   }
+  &:disabled {
+    opacity: 0.8;
+    cursor: not-allowed;
+  }
 }
 .btnValid {
   @include baseButton();
diff --git a/yarn.lock b/yarn.lock
index 921c761b..b713717b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3716,6 +3716,11 @@ data-urls@^2.0.0:
     whatwg-mimetype "^2.3.0"
     whatwg-url "^8.0.0"
 
+dayjs@^1.10.7:
+  version "1.10.7"
+  resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.7.tgz#2cf5f91add28116748440866a0a1d26f3a6ce468"
+  integrity sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig==
+
 debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9:
   version "2.6.9"
   resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
-- 
GitLab