diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 0000000000..498ee1ebb3
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,38 @@
+## Checklist:
+
+Necessary checkmarks:
+
+ - [] All Tests are Passing
+
+Type of change
+
+ - [] New feature
+ - [] Bug Fix
+
+Implements/Fixes:
+
+ description closes #
+
+Check the correct boxes
+
+ - [] This broke nothing
+ - [] This broke some stuff
+ - [] This broke everything
+
+Testing Changes
+
+ - [] No Tests have been changed
+ - [] Some Tests have been changed
+ - [] All of the Tests have been changed(Please describe what in the world happened)
+
+Checklist:
+
+ - [] My code has no unused/commented out code
+ - [] I have reviewed my code
+ - [] I have commented my code, particularly in hard-to-understand areas
+ - [] I have fully tested my code
+ - [] I have added one or more people as "Reviewers" to review & merge
+
+(For Fun!)Please Include a link to a gif of your feelings about this branch
+
+Link:
diff --git a/README.md b/README.md
index 0ccaeef0f0..55d3eb8e94 100644
--- a/README.md
+++ b/README.md
@@ -1,78 +1,39 @@
-# FitLit Starter Kit
-
-The details of this project are outline in [this project spec](http://frontend.turing.io/projects/fitlit.html).
-
-## Setup
-
-1. Within your group, decide on one person to have the project repository (repo) on their GitHub account. Then, that person should fork this repo - on the top right corner of this page, click the **Fork** button.
-1. Both memebers of the group should clone down the _forked_ repo. Since you don't want to name your project "activity-tracker-starter", you can use an optional argument when you run git clone (you replace the [...] with the terminal command arguments): `git clone [remote-address] [what you want to name the repo]`
-1. Once you have cloned the repo, change into the directory and install the project dependencies. Run `npm install` to install project dependencies.
-1. Run `npm start` in the terminal to see the HTML page (you should see some boilerplate HTML displayed on the page). `Control + C` is the command to stop running the local server. Closing the terminal without stopping the server first could allow the server to continue to run in the background and cause problems. This command is not specific to Webpack; make note of it for future use.
-1. Make sure both members of your team are collaborators on the forked repo.
-1. Do not run `npm audit fix --force`. This will update to the latest version of packages. We need to be using `webpack-dev-server@3.11.2` which is not the latest version. If you start to run into Webpack errors, first check that all group members are using the correct version.
-
-## Testing
-
-There is no boilerplate for testing in this starter-kit repo. You will need to set this up yourself. However, if you ran `npm install`, then the tooling you need to start testing is already installed (`mocha` and `chai`).
-
-
-## Data Model
-
-**Users**
-
-```
-[
- {
- "id": [number],
- "name": [string],
- "address": [string],
- "email": [string],
- "strideLength": [number - feet],
- "dailyStepGoal": [number - steps],
- "friends": [array - one-way connection to other user(s)]
- },
- ...more user data
-]
-```
-
-**Activity**
-
-```
-[
- {
- "userID": [number],
- "date": [string YYYY/MM/DD],
- "numSteps": [number - steps],
- "minutesActive": [number - minutes],
- "flightsOfStairs": [number - flights]
- },
- ...more activity data
-]
-```
-
-**Hydration**
-
-```
-[
- {
- "userID": [number],
- "date": [string YYYY/MM/DD],
- "numOunces": [number - ounces]
- },
- ...more hydration data
-]
-```
-
-**Sleep**
-
-```
-[
- {
- "userID": [number],
- "date": [string YYYY/MM/DD],
- "hoursSlept": [number - hours],
- "sleepQuality": [number - unitless]
- },
- ...more sleep data
-]
-```
+# FitLit
+## Abstract
+
+Staying in shape can be difficult. With all the stresses of life, keeping track of basic health statistics such as step count, fluid intake, and sleep can easily get away from you. Fit Lit is a web application designed to help users stay on track! Fit lit takes step count, sleep quality and longevity, and water consumed, stores it using API's, and then that data in an easily readable, helpful display.
+
+## Context
+
+This project was completed during two 1 week sprints in the second module of the Turing Program. The first sprint focused on implementing Test Driven Development (TDD), building an understanding of using asynchronous JavaScript to retrieve data from RESTful API's, and using GitHub Projects to plan and execute remote group work. The second sprint focused primarily on implementing feedback and building extensions on an existing code base, POSTing data to a local API, and utilizing third party extensions to display user data.
+
+## Installation
+
+1. Fork and clone this repo.
+2. Type `cd fitlit` to move into the root directory.
+3. Run `npm install`
+4. Run `npm start`
+5. copy and paste the provided url into a new web page
+6. Fork and clone [the local API repo](https://github.com/turingschool-examples/fitlit-api)
+7. In a seperate terminal, CD into it
+8. Run npm install
+9. Run npm start, navigate to Local Host 8080
+10. To stop the local server from running in your terminal use command + c
+
+## FitLit at a glance
+![Giph of project](https://media0.giphy.com/media/skPpSh8M5vEO4zQGqG/giphy.gif)
+## Technologies Used
+- JavaScript
+- HTML5
+- (S)CSS
+- Mocha
+- Chai
+- webpack
+- ### third party extensions
+ - chartjs
+
+## Contributors
+- Ashlee Webb: [github](https://github.com/AshleeAWebb) | [linkedin](https://www.linkedin.com/in/ashlee-webb-0b592199/)
+- Adam Meza: [github](https://github.com/Adam-Meza) | [linkedin](https://www.linkedin.com/in/adam-meza/)
+- Rachel Brendel: [github](https://github.com/brendel-r) | [linkedin](https://www.linkedin.com/in/rachel-brendel-bb9673197/)
+- Patrick Ankiewicz: [github](https://github.com/Pma913) | [linkedin](https://www.linkedin.com/in/patrick-ankiewicz/)
diff --git a/dist/index.html b/dist/index.html
index 444322806c..65414eae60 100644
--- a/dist/index.html
+++ b/dist/index.html
@@ -1,14 +1,84 @@
-
-
-
- Fitlit
-
-
- Activity Tracker
-
-
-
-
-
+
+
+
+
+
+ FitLit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Activity
+
+ Activity Chart
+
+
+
+
+ ×
+
+
+
+
+
+
+
+
+
+ Hydration
+
+
+
+
+
+ Sleep
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/package.json b/package.json
index 90731f1d8f..e102c88fc9 100644
--- a/package.json
+++ b/package.json
@@ -22,5 +22,9 @@
"webpack": "^5.38.1",
"webpack-cli": "^4.7.0",
"webpack-dev-server": "^3.11.2"
+ },
+ "dependencies": {
+ "chart.js": "^4.2.1",
+ "dayjs": "^1.11.7"
}
}
diff --git a/src/Activity.js b/src/Activity.js
new file mode 100644
index 0000000000..a71029e381
--- /dev/null
+++ b/src/Activity.js
@@ -0,0 +1,24 @@
+class Activity {
+ constructor(data, stride) {
+ this.data = data;
+ this.userStride = stride;
+ };
+
+ getDailyActivityInfo(date, infoType) {
+ if (infoType === 'minutesActive' || infoType === 'numSteps') {
+ return this.data.find(activity => activity.date === date)[infoType];
+ } else {
+ return `${infoType} is not a valid argument!`;
+ };
+ };
+
+ calculateMiles(date) {
+ return parseFloat(((this.getDailyActivityInfo(date, 'numSteps') * this.userStride) / 5280).toFixed(2))
+ };
+
+ getLatestWeek() {
+ return this.data.map(activity => activity.numSteps).slice(0,7);
+ };
+};
+
+export default Activity;
\ No newline at end of file
diff --git a/src/Hydration.js b/src/Hydration.js
new file mode 100644
index 0000000000..53ddc2bfb0
--- /dev/null
+++ b/src/Hydration.js
@@ -0,0 +1,31 @@
+class Hydration {
+ constructor(data) {
+ this.data = data;
+ };
+
+ findAvgDailyHydration() {
+ if (!this.data.length) {
+ return 'No Hydration Data Found';
+ };
+ const dailyAvg = this.data.reduce((total, water) => {
+ total.ounces += water.numOunces;
+ total.count += 1;
+ return total;
+ }, { ounces: 0, count: 0 });
+ return Math.round(dailyAvg.ounces / dailyAvg.count);
+ };
+
+ getHydrationSpecificDay(date) {
+ if (!this.data.length) {
+ return 'No Hydration Data Found';
+ };
+ const consumptionByDate = this.data.find(specficDate => specficDate.date === date);
+ return consumptionByDate.numOunces;
+ };
+
+ findWeeklyHydration() {
+ return this.data.map(water => water.numOunces).slice(0,7);
+ };
+};
+
+export default Hydration;
\ No newline at end of file
diff --git a/src/Sleep.js b/src/Sleep.js
new file mode 100644
index 0000000000..5dbe03c66f
--- /dev/null
+++ b/src/Sleep.js
@@ -0,0 +1,37 @@
+class Sleep {
+ constructor(data){
+ this.data = data;
+ };
+
+ getAverage(dataType) {
+ if (dataType === "hoursSlept" || dataType === "sleepQuality") {
+ let total = this.data.reduce((acc, currentValue) => {
+ acc += currentValue[dataType];
+ return acc;
+ }, 0)
+ return parseFloat((total / this.data.length).toFixed(4));
+ } else {
+ return `${dataType} is not a valid argument!`;
+ };
+ };
+
+ getInfoForSpecificDate(date, infoType) {
+ if (this.data.some(sleep => sleep.date === date)) {
+ return this.data.find(sleep => sleep.date === date)[infoType];
+ } else {
+ return "There is no data for this date";
+ };
+ };
+
+ getInfoForPastWeek(infoType) {
+ if (infoType === "hoursSlept" || infoType === "sleepQuality") {
+ return this.data
+ .map(sleep => sleep[infoType])
+ .slice(0,7);
+ } else {
+ return `${infoType} is not a valid argument!`;
+ };
+ };
+};
+
+export default Sleep;
\ No newline at end of file
diff --git a/src/SomeClassYouChangeTheName.js b/src/SomeClassYouChangeTheName.js
deleted file mode 100644
index adc57e422e..0000000000
--- a/src/SomeClassYouChangeTheName.js
+++ /dev/null
@@ -1,6 +0,0 @@
-class SomeClassYouChangeTheName {
- // This is here only so you can see how a class is imported into the scripts.js file
- // Rename it and structure it however you need in the project
-}
-
-export default SomeClassYouChangeTheName;
\ No newline at end of file
diff --git a/src/User.js b/src/User.js
new file mode 100644
index 0000000000..8bf14b4a7a
--- /dev/null
+++ b/src/User.js
@@ -0,0 +1,41 @@
+class User {
+ constructor(userStats) {
+ this.id = userStats.id;
+ this.name = userStats.name || "User";
+ this.address = userStats.address;
+ this.email = userStats.email;
+ this.strideLength = userStats.strideLength;
+ this.dailyStepGoal = userStats.dailyStepGoal;
+ this.friends = userStats.friends;
+ this.activity = [];
+ this.sleep = [];
+ this.hydration = [];
+ };
+
+ getFriends(dataSet) {
+ if (this.friends === undefined) {
+ return "Embrace the Solitude";
+ } else if (this.friends.length) {
+ let friends = dataSet.filter(friend => this.friends.includes(friend.id));
+ return friends.map(buddy => {
+ let splitName = buddy.name.split(' ');
+ return splitName[0];
+ });
+ };
+ };
+
+ getAverage(dataSet) {
+ let total = dataSet.reduce((acc, userSet) => {
+ acc += userSet.dailyStepGoal;
+ return acc;
+ }, 0);
+ return total / dataSet.length;
+ };
+
+ getName() {
+ let splitName = this.name.split(' ');
+ return splitName[0];
+ };
+};
+
+export default User;
\ No newline at end of file
diff --git a/src/apiCalls.js b/src/apiCalls.js
index f26ab3fc82..1faa3f2aa0 100644
--- a/src/apiCalls.js
+++ b/src/apiCalls.js
@@ -1,5 +1,31 @@
-// Your fetch requests will live here!
+const fetchAPI = (url) => {
+ return fetch(url)
+ .then(data => data.json());
+};
+const fetchAllData = () => {
+ return Promise.all([
+ fetchAPI('http://localhost:3001/api/v1/users'),
+ fetchAPI('http://localhost:3001/api/v1/hydration'),
+ fetchAPI('http://localhost:3001/api/v1/sleep'),
+ fetchAPI('http://localhost:3001/api/v1/activity')
+ ]);
+};
-console.log('I will be a fetch request!')
+const postActivityData = (data) => {
+ return fetch('http://localhost:3001/api/v1/activity', {
+ method: 'POST',
+ body: JSON.stringify(data),
+ headers: {
+ 'Content-Type': 'application/json'
+ }
+ })
+};
+const fetchActivityData = () => {
+ return fetch('http://localhost:3001/api/v1/activity')
+}
+
+export { fetchAllData };
+export { postActivityData };
+export { fetchActivityData };
\ No newline at end of file
diff --git a/src/charts.js b/src/charts.js
new file mode 100644
index 0000000000..45c5c3a32e
--- /dev/null
+++ b/src/charts.js
@@ -0,0 +1,82 @@
+import Chart from 'chart.js/auto';
+
+let charts = [];
+
+let displayChart = (weekData, location, chartLabel) => {
+
+ const data = [ { day: "", activity:"" }, { day: "", activity:"" }, { day: "", activity:"" }, { day: "", activity:"" }, { day: "", activity: "" }, { day: "", activity: "" }, { day: "", activity: "" }, ];
+
+ let chart = new Chart(
+ location,
+ {
+ type: 'line',
+ color:'#000000',
+ data: {
+ labels: data.map(row => row.day),
+ datasets: [
+ {
+ label: chartLabel,
+ data: weekData,
+ pointRadius: 5,
+ borderColor: "#042048",
+ pointBackgroundColor: 'rgb(86, 153, 248)',
+ backgroundColor: 'rgba(86, 153, 248, 0.5)'
+ }
+ ]
+ },
+ options: {
+ plugins: {
+ tooltip: {
+ mode: 'index',
+ intersect: false
+ }
+ }
+ },
+ alt: 'Informational Chart on User Data'
+ }
+ );
+
+ charts.push(chart)
+};
+
+let displayChallengeChart = (location, user, friends) => {
+ friends.unshift(user)
+ const friendsArray = friends;
+ const data = friends.map(person => person.daysReached)
+
+ new Chart(
+ location,
+ {
+ type: 'bar',
+ color:'#042048',
+ data: {
+ labels: friendsArray.map(row => row.name),
+ datasets: [
+ {
+ backgroundColor: "#042048",
+ barThickness: 6,
+ label: "Days Your Friends Met Their Goal",
+ data: data,
+ borderRadius: 1,
+ borderColor: "#042048",
+ borderWidth: 3,
+ backgroundColor: 'rgba(86, 153, 248, 0.5)'
+ }
+ ]
+ },
+ options:{
+ scales:{
+ y:{
+ beginAtZero: true
+ }
+ }
+ },
+ alt: "Challenge Chart with User's Friends"
+ }
+ );
+};
+
+export { displayChallengeChart };
+export { displayChart };
+export { charts }
+
diff --git a/src/css/styles.css b/src/css/styles.css
index b4a2b0d298..3a5fcd3632 100644
--- a/src/css/styles.css
+++ b/src/css/styles.css
@@ -1,5 +1,265 @@
-body, html {
- background-image: linear-gradient(to top, #ff9a9e 0%, #fecfef 99%, #fecfef 100%);
- background-repeat: no-repeat;
+/* variables */
+/* wide ranging */
+* {
+ margin: 0;
+ max-width: auto;
+ padding: 0;
+ font-family: "Lexend", sans-serif;
+}
+
+body, header, .activity-container {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-evenly;
+}
+
+.info-box,
+div,
+.activity-info,
+.activity,
+.info-card,
+.input-box {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+body {
+ background: radial-gradient(circle at center, #64aef8, #426eb0, #052c62), 100%;
+ font-size: 18px;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: 10px;
+ max-width: 100%;
+ overflow-wrap: normal;
+ padding: 0px 200px;
+}
+
+header {
+ align-items: center;
+ width: 100vw;
+ margin: 0;
+ color: white;
+}
+
+section {
+ display: flex;
+ justify-content: space-evenly;
+ width: 100vw;
+}
+
+ul {
+ height: 250px;
+ width: 350px;
+ padding: 5px;
+}
+
+li {
+ list-style-type: none;
+}
+
+.button {
+ box-shadow: -2px 0px 6px 0px rgba(86, 153, 248, 0.5);
+ border: rgba(86, 153, 248, 0.5) solid 4px;
+ padding: 10px;
+ background-color: white;
+ color: black;
+ border-radius: 50px;
+}
+.button:hover, .button:focus {
+ background-color: rgb(86, 153, 248);
+ text-decoration: none;
+ cursor: pointer;
+}
+
+.info-box, div {
+ justify-content: center;
+ height: 18vh;
+ width: 35vw;
+ margin: 10px;
+ padding: 10px;
+ border-radius: 50px;
+}
+
+/* activity styling */
+.activity-container {
+ align-items: center;
+ height: 300px;
+ box-shadow: -2px 0px 6px 0px rgba(86, 153, 248, 0.5);
+ background-color: white;
+ border-radius: 50px;
+}
+
+.activity-info-box {
height: 100%;
-}
\ No newline at end of file
+ width: 25%;
+ padding: 10px;
+}
+.activity-info-box h2 {
+ font-size: 20px;
+}
+
+.activity-chart {
+ height: 250px;
+ width: 320px;
+}
+
+.activity-info {
+ width: 350px;
+ height: 90px;
+}
+
+.activity {
+ border-radius: 50px;
+ justify-content: center;
+ border: none;
+}
+
+/*Other boxes */
+.sleep, .activity, .hydration {
+ background-color: #fff;
+ box-shadow: -3px 0px 6px 1px rgba(86, 153, 248, 0.5);
+}
+
+.info-card {
+ background-color: white;
+ border-radius: 50px;
+ margin: 8px;
+ display: flex;
+ flex-direction: column;
+ box-shadow: -2px 0px 6px 0px rgba(86, 153, 248, 0.5);
+}
+
+/* logo, header, user info */
+.logo {
+ display: flex;
+ width: 150px;
+ height: 150px;
+ margin: 20px auto;
+ shape-outside: circle();
+ -webkit-clip-path: circle();
+ clip-path: circle();
+ background: #5699f8;
+}
+
+.logo img {
+ display: block;
+ height: 100%;
+ -o-object-fit: contain;
+ object-fit: contain;
+ width: 100%;
+}
+
+.user-main {
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-end;
+ align-items: flex-start;
+ min-width: 400px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.user-name {
+ display: flex;
+ font-size: 30px;
+}
+
+.user-name, .user-info {
+ shape-outside: circle();
+ margin-left: 10px;
+}
+
+/* modal formatting */
+form {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ height: 100%;
+}
+
+.modal {
+ display: none;
+ position: fixed;
+ z-index: 1;
+ top: 0%;
+ width: 75%;
+ height: 50%;
+ max-width: -moz-fit-content;
+ max-width: fit-content;
+ background-color: rgb(255, 255, 255);
+ border: 6px solid rgb(86, 153, 248);
+ padding-top: 2px;
+ left: 50%;
+ transform: translateX(-50%);
+}
+
+.modal-content {
+ background-color: #fefefe;
+ margin: auto;
+ padding: 20px;
+ border: 1px solid rgb(86, 153, 248);
+ width: 50%;
+}
+
+.data-input {
+ border-radius: 10px;
+ width: 200px;
+ height: 30px;
+ margin: 2px;
+ text-align: center;
+}
+
+.input-box {
+ padding: 2%;
+ width: 500px;
+ justify-content: space-between;
+}
+
+.user-input {
+ width: 150px;
+ margin-left: 185px;
+}
+
+.close-btn {
+ margin: 10px;
+ color: black;
+ float: right;
+ font-size: 36px;
+ font-weight: bold;
+}
+.close-btn:hover, .close-btn:focus {
+ color: rgb(86, 153, 248);
+ text-decoration: none;
+ cursor: pointer;
+}
+
+.open-modal {
+ position: absolute;
+ top: 470px;
+}
+
+/* media queries */
+@media screen and (max-width: 600px) {
+ header {
+ flex-direction: column;
+ align-items: center;
+ }
+ .info-box {
+ width: 90%;
+ max-width: 100vh;
+ font-size: 20px;
+ }
+ .card-title {
+ width: 90%;
+ }
+ section {
+ flex-direction: column;
+ align-items: center;
+ }
+ .input-box {
+ justify-content: center;
+ width: 200px;
+ }
+}/*# sourceMappingURL=styles.css.map */
\ No newline at end of file
diff --git a/src/css/styles.css.map b/src/css/styles.css.map
new file mode 100644
index 0000000000..f8605d3389
--- /dev/null
+++ b/src/css/styles.css.map
@@ -0,0 +1 @@
+{"version":3,"sources":["styles.scss","styles.css"],"names":[],"mappings":"AAAA,cAAA;AAIA,iBAAA;AACA;EACE,SAAA;EACA,eAAA;EACA,UAAA;EACA,iCAAA;ACFF;;ADKA;EACE,aAAA;EACA,mBAAA;EACA,6BAAA;ACFF;;ADKA;;;;;;EAME,aAAA;EACA,sBAAA;EACA,mBAAA;ACFF;;ADKA;EACE,8EAAA;EACA,eAAA;EACA,mBAAA;EACA,eAAA;EACA,SAAA;EACA,eAAA;EACA,qBAAA;EACA,kBAAA;ACFF;;ADKA;EACE,mBAAA;EACA,YAAA;EACA,SAAA;EACA,YAAA;ACFF;;ADKA;EACE,aAAA;EACA,6BAAA;EACA,YAAA;ACFF;;ADKA;EACE,aAAA;EACA,YAAA;EACA,YAAA;ACFF;;ADKE;EACE,qBAAA;ACFJ;;ADKA;EACE,oDAAA;EACA,yCAAA;EACA,aAAA;EACA,uBAAA;EACA,YAAA;EACA,mBAAA;ACFF;ADIE;EACE,mCAvEG;EAwEH,qBAAA;EACA,eAAA;ACFJ;;ADMA;EACE,uBAAA;EACA,YAAA;EACA,WAAA;EACA,YAAA;EACA,aAAA;EACA,mBAAA;ACHF;;ADMA,qBAAA;AAEA;EACE,mBAAA;EACA,aAAA;EACA,oDAAA;EACA,uBAAA;EACA,mBAAA;ACJF;;ADOE;EACE,YAAA;EACA,UAAA;EACA,aAAA;ACJJ;ADMI;EACE,eAAA;ACJN;;ADQE;EACE,aAAA;EACA,YAAA;ACLJ;;ADQE;EACE,YAAA;EACA,YAAA;ACLJ;;ADQE;EACE,mBAAA;EACA,uBAAA;EACA,YAAA;ACLJ;;ADQA,eAAA;AACA;EACE,sBAAA;EACA,oDAAA;ACLF;;ADQA;EACE,uBAAA;EACA,mBAAA;EACA,WAAA;EACA,aAAA;EACA,sBAAA;EACA,oDAAA;ACLF;;ADQA,4BAAA;AACA;EACE,aAAA;EACA,YAAA;EACA,aAAA;EACA,iBAAA;EACA,uBAAA;EACA,2BAAA;UAAA,mBAAA;EACA,mBAAA;ACLF;;ADSE;EACE,cAAA;EACA,YAAA;EACA,sBAAA;KAAA,mBAAA;EACA,WAAA;ACNJ;;ADSA;EACE,aAAA;EACA,sBAAA;EACA,yBAAA;EACA,uBAAA;EACA,gBAAA;EACA,gBAAA;EACA,uBAAA;EACA,mBAAA;ACNF;;ADSE;EACE,aAAA;EACA,eAAA;ACNJ;;ADSE;EACE,uBAAA;EACA,iBAAA;ACNJ;;ADSA,qBAAA;AACA;EACE,aAAA;EACA,sBAAA;EACA,uBAAA;EACA,YAAA;ACNF;;ADSA;EACE,aAAA;EACA,eAAA;EACA,UAAA;EACA,OAAA;EACA,UAAA;EACA,WAAA;EACA,2BAAA;EAAA,sBAAA;EACA,oCAAA;EACA,mCAAA;EACA,gBAAA;EACA,SAAA;EACA,2BAAA;ACNF;;ADSA;EACE,yBAAA;EACA,YAAA;EACA,aAAA;EACA,mCAAA;EACA,UAAA;ACNF;;ADSA;EACE,mBAAA;EACA,YAAA;EACA,YAAA;EACA,WAAA;EACA,kBAAA;ACNF;;ADSA;EACE,WAAA;EACA,YAAA;EACA,8BAAA;ACNF;;ADSA;EACE,YAAA;EACA,kBAAA;ACNF;;ADSA;EACE,YAAA;EACA,YAAA;EACA,YAAA;EACA,eAAA;EACA,iBAAA;ACNF;ADQE;EACE,wBA3OG;EA4OH,qBAAA;EACA,eAAA;ACNJ;;ADUA;EACE,kBAAA;EACA,UAAA;ACPF;;ADUA,kBAAA;AACA;EACE;IACE,sBAAA;IACA,mBAAA;ECPF;EDUA;IACE,UAAA;IACA,gBAAA;IACA,eAAA;ECRF;EDWA;IACE,UAAA;ECTF;EDYA;IACE,sBAAA;IACA,mBAAA;ECVF;EDaA;IACE,uBAAA;IACA,YAAA;ECXF;AACF","file":"styles.css"}
\ No newline at end of file
diff --git a/src/css/styles.scss b/src/css/styles.scss
new file mode 100644
index 0000000000..b86613dfe9
--- /dev/null
+++ b/src/css/styles.scss
@@ -0,0 +1,336 @@
+/* variables */
+$blue: rgb(86, 153, 248);
+$transparent-blue: rgba(86, 153, 248, 0.5);
+$warm-black: rgba(26, 14, 1, 0.5);
+
+/* wide ranging */
+* {
+ margin: 0;
+ max-width: auto;
+ padding: 0;
+ font-family: "Lexend", sans-serif;
+}
+
+body, header, .activity-container {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-evenly;
+}
+
+.info-box,
+div,
+.activity-info,
+.activity,
+.info-card,
+.input-box {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+body {
+ background: radial-gradient(circle at center,#64aef8, #426eb0, #052c62), 100%;
+ font-size: 20px;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: 10px;
+ max-width: 100%;
+ overflow-wrap: normal;
+ padding: 0px 200px;
+}
+
+header {
+ align-items: center;
+ width: 100vw;
+ margin: 0;
+ color:white;
+}
+
+section {
+ display: flex;
+ justify-content: space-evenly;
+ width: 100vw;
+}
+
+ul {
+ height: 250px;
+ width: 350px;
+ padding: 5px;
+}
+
+ li {
+ list-style-type: none;
+ }
+
+.button{
+ box-shadow: -2px 0px 6px 0px $transparent-blue;
+ border: $transparent-blue solid 4px;
+ padding: 10px;
+ background-color: white;
+ color:black;
+ border-radius: 50px;
+
+ &:hover, &:focus {
+ background-color: $blue;
+ text-decoration: none;
+ cursor: pointer;
+ }
+}
+
+.info-box, div {
+ justify-content: center;
+ height: 18vh;
+ width: 35vw;
+ margin: 10px;
+ padding: 10px;
+ border-radius: 50px;
+}
+
+/* activity styling */
+
+.activity-container {
+ align-items: center;
+ height: 300px;
+ box-shadow: -2px 0px 6px 0px $transparent-blue;
+ background-color: white;
+ border-radius: 50px;
+}
+
+ .activity-info-box {
+ height: 100%;
+ width: 25%;
+ padding: 10px;
+ position: relative;
+
+ h2 {
+ font-size: 20px;
+ }
+ }
+
+ .activity-chart {
+ height: 250px;
+ width: 320px;
+ }
+
+ .activity-info {
+ width: 350px;
+ height: 90px;
+ }
+
+ .activity {
+ border-radius: 50px;
+ justify-content: center;
+ border: none;
+ }
+ .activityUserStat {
+ margin-top: 15px;
+ }
+
+/*Other boxes */
+.sleep, .activity, .hydration {
+ background-color: #fff;
+ box-shadow: -3px 0px 6px 1px $transparent-blue;
+}
+
+.info-card {
+ background-color: white;
+ border-radius: 50px;
+ margin: 8px;
+ display: flex;
+ flex-direction: column;
+ box-shadow: -2px 0px 6px 0px $transparent-blue;
+}
+
+/* logo, header, user info */
+.logo {
+ display: flex;
+ width: 175px;
+ height: 175px;
+ clip-path: circle();
+ background: #5699f8;
+ padding: 0px;
+ margin-left: 200px;
+ float: left;
+}
+
+.logo img {
+ display: block;
+ height: 95%;
+ object-fit: contain;
+ width: 95%;
+}
+
+.user-main {
+ padding: 0px;
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-end;
+ align-items: flex-start;
+ min-width: 600px;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ border-radius: 0px;
+ text-shadow: 10px 10px 10px $warm-black;
+}
+
+.user-name {
+ display: flex;
+ font-size: 30px;
+}
+
+.user-info {
+ font-size: 20px;
+}
+
+/* modal formatting */
+form {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ height: 100%;
+}
+
+.modal {
+ display: none;
+ position: fixed;
+ z-index: 1;
+ top: 0%;
+ width: 75%;
+ height: 50%;
+ max-width: fit-content;
+ background-color: rgba(255, 255, 255);
+ border: 6px solid $blue;
+ padding-top: 2px;
+ left: 50%;
+ transform: translateX(-50%);
+}
+
+.modal-content {
+ background-color: #fefefe;
+ margin: auto;
+ padding: 20px;
+ border: 1px solid $blue;
+ width: 50%;
+}
+
+.data-input {
+ border-radius: 10px;
+ width: 200px;
+ height: 30px;
+ margin: 2px;
+ text-align: center;
+}
+
+.input-box {
+ padding: 2%;
+ width: 500px;
+ justify-content: space-between;
+}
+
+.user-input {
+ width: 150px;
+ margin-left: 185px
+}
+
+.close-btn {
+ margin: 10px;
+ color: black;
+ float: right;
+ font-size: 36px;
+ font-weight: bold;
+
+ &:hover, &:focus {
+ color: $blue;
+ text-decoration: none;
+ cursor: pointer;
+ }
+}
+
+.open-modal{
+ position: absolute;
+ margin-top: 150px;
+ z-index: inherit;
+}
+
+/* media queries */
+@media screen and (max-width: 600px) {
+ body {
+ padding: 20px;
+ }
+
+ header {
+ flex-direction: column;
+ align-items: center;
+ }
+
+ .activity-container {
+ flex-direction: column;
+ max-width: 100%;
+ flex-wrap: wrap;
+ align-items: center;
+ height: auto;
+ }
+
+ .info-box {
+ width: 90%;
+ max-width: 90%;
+ font-size: 20px;
+ }
+
+ .card-title {
+ width: 90%;
+ }
+
+ section {
+ flex-direction: column;
+ align-items: center;
+ width: 90%;
+ }
+
+ .input-box {
+ justify-content: center;
+ width: 90%;
+ }
+
+ .user-main {
+ width: 90%;
+ min-width: 90%;
+ text-align: center;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ overflow: visible;
+ margin-top: 0;
+ }
+
+ .user-info {
+ display: none;
+ }
+
+ .logo {
+ margin-left: 0;
+ }
+
+ .user-main{
+ margin-top: 0;
+ }
+
+ .activity-info-box {
+ max-width: 90%;
+ }
+
+ .modal {
+ width: 90%;
+ height: auto;
+ }
+
+ .modal-content {
+ width: 90%;
+ }
+}
+
+
+
+
+
+
diff --git a/src/data/activity-test-data.js b/src/data/activity-test-data.js
new file mode 100644
index 0000000000..cf40f69baf
--- /dev/null
+++ b/src/data/activity-test-data.js
@@ -0,0 +1,59 @@
+export default {
+ activityTestData: [
+ {
+ "userID": 1,
+ "date": "2023/03/20",
+ "numSteps": 7362,
+ "minutesActive": 261,
+ "flightsOfStairs": 26
+ },
+ {
+ "userID": 1,
+ "date": "2023/03/22",
+ "numSteps": 3049,
+ "minutesActive": 125,
+ "flightsOfStairs": 43
+ },
+ {
+ "userID": 1,
+ "date": "2023/03/23",
+ "numSteps": 12970,
+ "minutesActive": 282,
+ "flightsOfStairs": 38
+ },
+ {
+ "userID": 1,
+ "date": "2023/03/24",
+ "numSteps": 8934,
+ "minutesActive": 294,
+ "flightsOfStairs": 19
+ },
+ {
+ "userID": 1,
+ "date": "2023/03/25",
+ "numSteps": 8443,
+ "minutesActive": 136,
+ "flightsOfStairs": 43
+ },
+ {
+ "userID": 1,
+ "date": "2023/03/26",
+ "numSteps": 13297,
+ "minutesActive": 116,
+ "flightsOfStairs": 13
+ },
+ {
+ "userID": 1,
+ "date": "2023/03/27",
+ "numSteps": 7765,
+ "minutesActive": 74,
+ "flightsOfStairs": 31
+ },
+ {
+ "userID": 1,
+ "date": "2023/03/28",
+ "numSteps": 7255,
+ "minutesActive": 42,
+ "flightsOfStairs": 28
+ }]
+}
\ No newline at end of file
diff --git a/src/data/hydration-test-data.js b/src/data/hydration-test-data.js
new file mode 100644
index 0000000000..947fa6fa09
--- /dev/null
+++ b/src/data/hydration-test-data.js
@@ -0,0 +1,41 @@
+export default { hydrationTestData: [{
+ "userID": 1,
+ "date": "2023/03/02",
+ "numOunces": 28
+ },
+ {
+ "userID": 1,
+ "date": "2023/03/05",
+ "numOunces": 35
+ },
+ {
+ "userID": 1,
+ "date": "2023/03/10",
+ "numOunces": 95
+ },
+ {
+ "userID": 1,
+ "date": "2023/03/12",
+ "numOunces": 74
+ },
+ {
+ "userID": 1,
+ "date": "2023/03/16",
+ "numOunces": 47
+ },
+ {
+ "userID": 1,
+ "date": "2023/03/18",
+ "numOunces": 86
+ },
+ {
+ "userID": 1,
+ "date": "2023/03/20",
+ "numOunces": 74
+ },
+ {
+ "userID": 1,
+ "date": "2023/03/25",
+ "numOunces": 36
+ }
+ ]};
\ No newline at end of file
diff --git a/src/data/sleep-test-data.js b/src/data/sleep-test-data.js
new file mode 100644
index 0000000000..a6be324a74
--- /dev/null
+++ b/src/data/sleep-test-data.js
@@ -0,0 +1,72 @@
+export default { sleepTestData: [
+ {"userID":1,"date":"2023/03/24","hoursSlept":9.6,"sleepQuality":4.3},
+ {"userID":2,"date":"2023/03/24","hoursSlept":8.4,"sleepQuality":3.5},
+ {"userID":3,"date":"2023/03/24","hoursSlept":9.7,"sleepQuality":4.7},
+ {"userID":4,"date":"2023/03/24","hoursSlept":4.7,"sleepQuality":3},
+ {"userID":5,"date":"2023/03/24","hoursSlept":8,"sleepQuality":3.1},
+ {"userID":6,"date":"2023/03/24","hoursSlept":4.2,"sleepQuality":1.2},
+ {"userID":7,"date":"2023/03/24","hoursSlept":4.1,"sleepQuality":3.9},
+ {"userID":8,"date":"2023/03/24","hoursSlept":9.2,"sleepQuality":1.6},
+ {"userID":9,"date":"2023/03/24","hoursSlept":4.8,"sleepQuality":2.5},
+ {"userID":10,"date":"2023/03/24","hoursSlept":7.2,"sleepQuality":2.2},
+ {"userID":11,"date":"2023/03/24","hoursSlept":7.2,"sleepQuality":1},
+ {"userID":12,"date":"2023/03/24","hoursSlept":4,"sleepQuality":3.1},
+ {"userID":13,"date":"2023/03/24","hoursSlept":6.5,"sleepQuality":1.4},
+ {"userID":14,"date":"2023/03/24","hoursSlept":5.3,"sleepQuality":4.7},
+ {"userID":15,"date":"2023/03/24","hoursSlept":10,"sleepQuality":2.4},
+ {"userID":16,"date":"2023/03/24","hoursSlept":6.7,"sleepQuality":2.9},
+ {"userID":17,"date":"2023/03/24","hoursSlept":6.3,"sleepQuality":3.6},
+ {"userID":18,"date":"2023/03/24","hoursSlept":4.2,"sleepQuality":4.6},
+ {"userID":19,"date":"2023/03/24","hoursSlept":9.9,"sleepQuality":4.7},
+ {"userID":20,"date":"2023/03/24","hoursSlept":7.4,"sleepQuality":1.7},
+ {"userID":21,"date":"2023/03/24","hoursSlept":10.9,"sleepQuality":3.3},
+ {"userID":22,"date":"2023/03/24","hoursSlept":8.9,"sleepQuality":2},
+ {"userID":23,"date":"2023/03/24","hoursSlept":5.7,"sleepQuality":3.4},
+ {"userID":24,"date":"2023/03/24","hoursSlept":8.9,"sleepQuality":1.2},
+ {"userID":25,"date":"2023/03/24","hoursSlept":6,"sleepQuality":3.4},
+ {"userID":26,"date":"2023/03/24","hoursSlept":8,"sleepQuality":1.5},
+ {"userID":27,"date":"2023/03/24","hoursSlept":9.6,"sleepQuality":4.9},
+ {"userID":28,"date":"2023/03/24","hoursSlept":10,"sleepQuality":4.9},
+ {"userID":29,"date":"2023/03/24","hoursSlept":7.9,"sleepQuality":2.2},
+ {"userID":1,"date":"2023/03/25","hoursSlept":6.3,"sleepQuality":3.3},
+ {"userID":2,"date":"2023/03/25","hoursSlept":8.1,"sleepQuality":4.7},
+ {"userID":3,"date":"2023/03/25","hoursSlept":9.5,"sleepQuality":1.8},
+ {"userID":4,"date":"2023/03/25","hoursSlept":6.5,"sleepQuality":4.4},
+ {"userID":5,"date":"2023/03/25","hoursSlept":5.7,"sleepQuality":1.7},
+ {"userID":6,"date":"2023/03/25","hoursSlept":10.4,"sleepQuality":2.6},
+ {"userID":7,"date":"2023/03/25","hoursSlept":9.8,"sleepQuality":3},
+ {"userID":8,"date":"2023/03/25","hoursSlept":5.9,"sleepQuality":3},
+ {"userID":9,"date":"2023/03/25","hoursSlept":9.2,"sleepQuality":4.8},
+ {"userID":10,"date":"2023/03/25","hoursSlept":11,"sleepQuality":2.6},
+ {"userID":11,"date":"2023/03/25","hoursSlept":9.2,"sleepQuality":2.2},
+ {"userID":12,"date":"2023/03/25","hoursSlept":7.6,"sleepQuality":2.7},
+ {"userID":13,"date":"2023/03/25","hoursSlept":5.7,"sleepQuality":4.2},
+ {"userID":14,"date":"2023/03/25","hoursSlept":8.7,"sleepQuality":4.2},
+ {"userID":15,"date":"2023/03/25","hoursSlept":7.4,"sleepQuality":2.8},
+ {"userID":16,"date":"2023/03/25","hoursSlept":8.8,"sleepQuality":1.2},
+ {"userID":17,"date":"2023/03/25","hoursSlept":8.3,"sleepQuality":3.3},
+ {"userID":18,"date":"2023/03/25","hoursSlept":10.6,"sleepQuality":4.8},
+ {"userID":19,"date":"2023/03/25","hoursSlept":8.7,"sleepQuality":1.3},
+ {"userID":20,"date":"2023/03/25","hoursSlept":6.1,"sleepQuality":2.6},
+ {"userID":21,"date":"2023/03/25","hoursSlept":4.6,"sleepQuality":2.6},
+ {"userID":22,"date":"2023/03/25","hoursSlept":6.5,"sleepQuality":4.2},
+ {"userID":23,"date":"2023/03/25","hoursSlept":10.7,"sleepQuality":1.2},
+ {"userID":24,"date":"2023/03/25","hoursSlept":5.1,"sleepQuality":4.2},
+ {"userID":25,"date":"2023/03/25","hoursSlept":8.2,"sleepQuality":3.4},
+ {"userID":26,"date":"2023/03/25","hoursSlept":6.4,"sleepQuality":1},
+ {"userID":27,"date":"2023/03/25","hoursSlept":6.7,"sleepQuality":2},
+ {"userID":28,"date":"2023/03/25","hoursSlept":6.4,"sleepQuality":4.7},
+ {"userID":29,"date":"2023/03/25","hoursSlept":7.8,"sleepQuality":4.1},
+ {"userID":1,"date":"2023/03/26","hoursSlept":5.1,"sleepQuality":4.2},
+ {"userID":1,"date":"2023/03/27","hoursSlept":8.2,"sleepQuality":3.4},
+ {"userID":1,"date":"2023/03/28","hoursSlept":6.4,"sleepQuality":1},
+ {"userID":1,"date":"2023/03/29","hoursSlept":6.7,"sleepQuality":2},
+ {"userID":1,"date":"2023/03/30","hoursSlept":6.4,"sleepQuality":4.7},
+ {"userID":1,"date":"2023/03/31","hoursSlept":7.8,"sleepQuality":4.1}
+]
+
+
+
+
+
+}
\ No newline at end of file
diff --git a/src/data/user-test-data.js b/src/data/user-test-data.js
new file mode 100644
index 0000000000..98b9d16718
--- /dev/null
+++ b/src/data/user-test-data.js
@@ -0,0 +1,109 @@
+export default { userTestData: [
+ {
+ "id": 1,
+ "name": "Trystan Gorczany",
+ "address": "9484 Lucas Flat, West Kittymouth WA 67504",
+ "email": "Taurean_Pollich31@gmail.com",
+ "strideLength": 4,
+ "dailyStepGoal": 7000,
+ "friends": [
+ 5,
+ 43,
+ 46,
+ 11
+ ]
+ },
+ {
+ "id": 2,
+ "name": "Tyreek VonRueden",
+ "address": "623 Koelpin Skyway, Lake Luigichester MN 77576-1678",
+ "email": "Nicolette_Halvorson43@yahoo.com",
+ "strideLength": 4.5,
+ "dailyStepGoal": 9000,
+ "friends": [
+ 13,
+ 19,
+ 3
+ ]
+ },
+ {
+ "id": 3,
+ "name": "Colt Rohan",
+ "address": "48010 Balistreri Harbor, Cleobury IN 43317",
+ "email": "Wilford.Barton@gmail.com",
+ "strideLength": 2.7,
+ "dailyStepGoal": 3000,
+ "friends": [
+ 31,
+ 16,
+ 15,
+ 7
+ ]
+ },
+ {
+ "id": 4,
+ "name": "Evie Satterfield",
+ "address": "1378 Renner Island, Port Lincoln NE 06237-3602",
+ "email": "Adan66@yahoo.com",
+ "strideLength": 3.9,
+ "dailyStepGoal": 4000,
+ "friends": [
+ 21,
+ 32,
+ 8
+ ]
+ },
+ {
+ "id": 5,
+ "name": "Brycen Rutherford",
+ "address": "0770 Keeley Square, West Keyon SD 73400-6577",
+ "email": "Jerald55@yahoo.com",
+ "strideLength": 3.3,
+ "dailyStepGoal": 10000,
+ "friends": [
+ 5,
+ 46
+ ]
+ },
+ {
+ "id": 6,
+ "name": "Jillian Senger",
+ "address": "235 Geoffrey Highway, New Lavadaport CA 62933-3709",
+ "email": "Cortez51@gmail.com",
+ "strideLength": 4.3,
+ "dailyStepGoal": 10000,
+ "friends": [
+ 25,
+ 15,
+ 20
+ ]
+ },
+ {
+ "id": 7,
+ "name": "Elaina Mosciski",
+ "address": "307 Gerhard Pine, Luettgenton NC 60477",
+ "email": "Karolann.Kuvalis@yahoo.com",
+ "strideLength": 3,
+ "dailyStepGoal": 9000,
+ "friends": [
+ 7,
+ 46,
+ 43
+ ]
+ },
+ {
+ "id": 8,
+ "name": "Amir Lang",
+ "address": "75165 Zulauf Walks, North Dejaview NC 21971-9115",
+ "email": "Eudora.Stracke@yahoo.com",
+ "strideLength": 2.8,
+ "dailyStepGoal": 2000,
+ "friends": [
+ 46,
+ 8,
+ 29,
+ 33,
+ 10
+ ]
+ }
+]};
\ No newline at end of file
diff --git a/src/images/activity-logo.png b/src/images/activity-logo.png
new file mode 100644
index 0000000000..c4f43cae20
Binary files /dev/null and b/src/images/activity-logo.png differ
diff --git a/src/images/fitlit-logo.png b/src/images/fitlit-logo.png
new file mode 100644
index 0000000000..9051c4a600
Binary files /dev/null and b/src/images/fitlit-logo.png differ
diff --git a/src/images/hydration-logo.png b/src/images/hydration-logo.png
new file mode 100644
index 0000000000..c8d06fb5c9
Binary files /dev/null and b/src/images/hydration-logo.png differ
diff --git a/src/images/sleep-logo.png b/src/images/sleep-logo.png
new file mode 100644
index 0000000000..6fda07e1ea
Binary files /dev/null and b/src/images/sleep-logo.png differ
diff --git a/src/scripts.js b/src/scripts.js
index e26d2ab9b2..8d8cd0171b 100644
--- a/src/scripts.js
+++ b/src/scripts.js
@@ -1,20 +1,200 @@
-// This is the JavaScript entry file - your code begins here
-// Do not delete or rename this file ********
+// Webpack Links
+import { fetchAllData } from '../src/apiCalls';
+import { postActivityData } from '../src/apiCalls';
+import { fetchActivityData } from '../src/apiCalls';
+import { displayChart } from '../src/charts';
+import { displayChallengeChart } from '../src/charts';
+import { charts } from '../src/charts';
+import dayjs from 'dayjs';
+import './css/styles.scss';
+import './images/fitlit-logo.png';
+import './images/hydration-logo.png';
+import './images/activity-logo.png';
+import './images/sleep-logo.png';
+import User from '../src/User';
+import Sleep from '../src/Sleep';
+import Hydration from '../src/Hydration';
+import Activity from '../src/Activity';
+// Queury Selectors
+const firstName = document.getElementById('userName'),
+ userInfo = document.getElementById('userInfo'),
+ sleepInfo = document.getElementById('sleepInfoBox'),
+ sleepWeek = document.getElementById('sleepBoxWeek'),
+ hydrationInfo = document.getElementById('hydrationInfoBox'),
+ hydrationWeek = document.getElementById('hydrationBoxWeek'),
+ activityInfo = document.getElementById('activityInfoBox'),
+ activityWeek = document.getElementById('activityBoxWeek'),
+ userInputForm = document.querySelector('form'),
+ formInputs = document.querySelectorAll('.data-input'),
+ modal = document.getElementById('activityModal'),
+ userInputButton = document.getElementById('userInputBtn'),
+ openModalBtn = document.getElementById('openModalBtn'),
+ closeBtn = document.getElementById('close-btn'),
+ stepChallengeBox = document.getElementById('stepChallengeBox');
-// An example of how you tell webpack to use a CSS file
-import './css/styles.css';
+// Global Variables
+let users,
+ user,
+ userChallengeData,
+ friendsChallengeData = [],
+ inputs = [];
-// An example of how you tell webpack to use an image (also need to link to it in the index.html)
-import './images/turing-logo.png';
+formInputs.forEach(input => inputs.push(input));
+userInputButton.disabled = true;
-console.log('This is the JavaScript entry file - your code begins here.');
+// DM Methods
+let changeButton = () => {
+ if (inputs.every(input => input.value)) {
+ userInputButton.disabled = false;
+ }
+};
-// An example of how you tell webpack to use a JS file
+const getUserData = (infoType, array, userInst = user) => {
+ return array[infoType].filter(data => data.userID === userInst.id).reverse();
+};
-import userData from './data/users';
-console.log("User Data:", userData);
+const createFriends = (info) => {
+ user.friends = user.friends.map(friend => {
+ return new User(users.find(user => user.id === friend));
+ });
+ user.friends.forEach(friend => {
+ friend.activity = new Activity(getUserData('activityData', info[3], friend)); });
+};
-import SomeClassYouChangeTheName from './SomeClassYouChangeTheName';
+const postChallengeStats = () => {
+userChallengeData = getStepChallengeStats(user);
+user.friends.forEach(friend => {
+ friendsChallengeData.push(getStepChallengeStats(friend));
+});
+};
-const newClass = new SomeClassYouChangeTheName();
\ No newline at end of file
+const getStepChallengeStats = (challenger) => {
+const averageStepGoal = challenger.dailyStepGoal;
+const stepsForTheWeek = challenger.activity.getLatestWeek();
+const dailyGoalAchieved = stepsForTheWeek.filter((steps) => steps >= averageStepGoal);
+return { name: challenger.name, daysReached: dailyGoalAchieved.length };
+};
+
+//DOM methods
+
+const displayCurrentUser = (user) => {
+ firstName.innerText = `${user.getName()}`;
+ userInfo.innerHTML = `Address: ${user.address}
+ Email: ${user.email}
+ Stride Length: ${user.strideLength}
+ Daily Step Goal: ${user.dailyStepGoal}
+ Friends: ${user.getFriends(users)}
+ Your Step Goal Compared to All Users: ${user.dailyStepGoal}/${user.getAverage(users)} `
+};
+
+const displaySleepInfo = (sleep) => {
+ let latestSleep = sleep.data[sleep.data.length - 1],
+ pastWeekSleep = sleep.getInfoForPastWeek('hoursSlept'),
+ avgQuality = sleep.getAverage('sleepQuality'),
+ avgHours = sleep.getAverage('hoursSlept');
+
+ sleepInfo.innerHTML = `Latest Hours Slept: ${latestSleep.hoursSlept}
+ Latest Quality of Sleep: ${latestSleep.sleepQuality} Average Sleep Quality: ${avgQuality.toFixed(1)}
+ Average Hours Slept: ${avgHours.toFixed(1)} `
+ displayChart(pastWeekSleep, sleepWeek, "Sleep for the Week");
+};
+
+const displayHydration = (userId) => {
+ let currentDate = user.hydration.data[0].date;
+ let weekData = user.hydration.findWeeklyHydration();
+
+ hydrationInfo.innerHTML = `Average daily water intake: ${user.hydration.findAvgDailyHydration(userId)}oz
+ Fluid ounces drank today: ${user.hydration.getHydrationSpecificDay(currentDate)}oz `;
+ displayChart(weekData, hydrationWeek, "Hydration for the Week");
+};
+
+const displayActivity = () => {
+ let currentDate = user.activity.data[0].date;
+ let weekData = user.activity.getLatestWeek();
+
+ activityInfo.innerHTML = `Latest # of Steps: ${user.activity.getDailyActivityInfo(currentDate, 'numSteps')}
+ Latest # of Minutes Active: ${user.activity.getDailyActivityInfo(currentDate, 'minutesActive')}
+ Latest Distance Walked: ${user.activity.calculateMiles(currentDate)} `;
+ displayChart(weekData, activityWeek, "Activity for the Week");
+};
+
+const resetDOM = () => {
+ charts[2].destroy()
+ charts.pop(2)
+ displayActivity()
+
+ userInputForm.reset();
+ userInputButton.disabled = true;
+ modal.style.display = "none";
+}
+
+// Event Listeners
+window.addEventListener('load', () => {
+ fetchAllData()
+ .then(data => {
+ users = data[0].users;
+
+ user = new User(data[0].users[Math.floor(Math.random() * 50)]);
+ displayCurrentUser(user);
+
+ user.hydration = new Hydration(getUserData('hydrationData', data[1]));
+ displayHydration(user.id);
+
+ user.sleep = new Sleep(getUserData('sleepData', data[2]));
+ displaySleepInfo(user.sleep);
+
+ user.activity = new Activity(getUserData('activityData', data[3]), user.strideLength);
+ displayActivity(user.id);
+
+ createFriends(data);
+ postChallengeStats();
+ displayChallengeChart(stepChallengeBox, userChallengeData, friendsChallengeData);
+ })
+ .catch(err => console.log(err.message));
+});
+
+openModalBtn.onclick = function() {
+ modal.style.display = "block";
+};
+
+closeBtn.onclick = function() {
+ modal.style.display = "none";
+};
+
+window.onclick = function(event) {
+ if (event.target == modal) {
+ modal.style.display = "none";
+ };
+};
+
+inputs.forEach(input => input.addEventListener('input', changeButton));
+
+userInputForm.addEventListener('submit', function(event) {
+ event.preventDefault();
+
+ const userInputData = {
+ userID: user.id,
+ date: dayjs().format('YYYY/MM/DD'),
+ flightsOfStairs: parseInt(inputs.find(input => input.id === "flightsOfStairs").value),
+ minutesActive: parseInt(inputs.find(input => input.id === "activeMinutes").value),
+ numSteps: parseInt(inputs.find(input => input.id === "numSteps").value)
+ };
+
+
+
+ postActivityData(userInputData)
+ .then(res => res.json())
+ .then(res => {
+ console.log('successfully recorded: ', res);
+
+ fetchActivityData()
+ .then(res => res.json())
+ .then(data => {
+ user.activity = new Activity(getUserData('activityData', data), user.strideLength);
+ resetDOM()
+ })
+ .catch(err => console.log(err.message));
+ })
+ .catch(err => console.log(err.message));
+});
\ No newline at end of file
diff --git a/test/Activity-test.js b/test/Activity-test.js
new file mode 100644
index 0000000000..e2edfbe714
--- /dev/null
+++ b/test/Activity-test.js
@@ -0,0 +1,48 @@
+import { expect } from 'chai';
+import Activity from '../src/Activity';
+import activityTestData from '../src/data/activity-test-data.js';
+import User from '../src/User.js';
+import userTestData from '../src/data/user-test-data.js';
+
+describe('Activity', () => {
+ let user;
+ let activity;
+
+ beforeEach(() => {
+ user = new User(userTestData.userTestData[0]);
+ activity = new Activity(activityTestData.activityTestData.reverse(), 4);
+ user.activity = activity;
+ });
+
+ it('should check all the properties to see if they hold the data we want', () => {
+ let unsortedUser = new User(userTestData.userTestData[0]);
+ let activity2 = new Activity(activityTestData.activityTestData);
+ unsortedUser.activity = activity2;
+
+ expect(unsortedUser.activity.data).to.deep.equal(activityTestData.activityTestData);
+ });
+
+ it('should hold the users stride', () => {
+ expect(activity.userStride).to.equal(4);
+ });
+
+ it('should calculate minutes active for the lastest day', () => {
+ expect(user.activity.getDailyActivityInfo("2023/03/20", 'minutesActive')).to.deep.equal(261);
+ });
+
+ it('should be able to check the amount of steps for the latest day', () => {
+ expect(user.activity.getDailyActivityInfo("2023/03/20", 'numSteps')).to.deep.equal(7362);
+ });
+
+ it('should send an error if given a false arguement', () => {
+ expect(user.activity.getDailyActivityInfo("2023/03/20", 'Banana')).to.deep.equal('Banana is not a valid argument!');
+ });
+
+ it('should calculate miles for a given day', () => {
+ expect(user.activity.calculateMiles("2023/03/20")).to.equal(5.58);
+ });
+
+ it('should check how a each day in the last weeks steps compares to the goal', () => {
+ expect(user.activity.getLatestWeek()).to.deep.equal([ 7255, 7765, 13297, 8443, 8934, 12970, 3049]);
+ });
+});
\ No newline at end of file
diff --git a/test/Hydration-test.js b/test/Hydration-test.js
new file mode 100644
index 0000000000..1244241ced
--- /dev/null
+++ b/test/Hydration-test.js
@@ -0,0 +1,54 @@
+import { expect } from 'chai';
+import Hydration from '../src/Hydration';
+import hydrationTestData from '../src/data/hydration-test-data';
+
+describe('Hydration', () => {
+ let data;
+ let hydration;
+ let sadHydration;
+ beforeEach(() => {
+ data = hydrationTestData.hydrationTestData.reverse();
+ sadHydration = new Hydration([]);
+ hydration = new Hydration(data);
+ });
+
+ it('should be a function', () => {
+ expect(Hydration).to.be.a('function');
+ });
+
+ it('should be an instance of Hydration', () => {
+ expect(hydration).to.be.an.instanceOf(Hydration);
+ });
+
+ it('should store an array of hydration data', () => {
+ expect(hydration.data).to.deep.equal(data);
+ });
+
+ it('should have a user id, number of ounces, and date', () => {
+ const userData = data[0];
+ expect(userData.userID).to.equal(1);
+ expect(userData.date).to.equal("2023/03/02");
+ expect(userData.numOunces).to.equal(28);
+ });
+
+ it('should calculate the user\'s average fluid ounces consumed per day for all time', () => {
+ expect(hydration.findAvgDailyHydration(1)).to.equal(59);
+ });
+
+ it('should return message if user does not exist', () => {
+ expect(sadHydration.findAvgDailyHydration()).to.equal('No Hydration Data Found');
+ });
+
+ it('should return the a specfic days water consumption', () => {
+ expect(hydration.getHydrationSpecificDay('2023/03/02')).to.equal(28);
+ });
+
+ it('should return message if nothing logged that specfic day', () => {
+ expect(sadHydration.getHydrationSpecificDay('2023/03/03')).to.equal('No Hydration Data Found');
+ });
+
+ it('should return the user\'s total amount of water for 7 consecutive days', () => {
+ expect(hydration.findWeeklyHydration()).to.deep.equal([ 36, 74, 86, 47, 74, 95, 35 ]);
+ });
+});
+
diff --git a/test/Sleep-test.js b/test/Sleep-test.js
new file mode 100644
index 0000000000..aefc26f458
--- /dev/null
+++ b/test/Sleep-test.js
@@ -0,0 +1,59 @@
+import { expect } from 'chai';
+import Sleep from '../src/Sleep';
+import sleepTestData from '../src/data/sleep-test-data.js';
+
+describe('Sleep Repository', () => {
+ let sleep;
+ beforeEach(() => {
+ let specificData = sleepTestData.sleepTestData.filter(sleep => sleep.userID === 1)
+ sleep = new Sleep(specificData.reverse());
+ });
+
+ it('should be a function', () => {
+ expect(Sleep).to.be.a('function');
+ });
+
+ it('should be an instance of Sleep', () => {
+ expect(sleep).to.be.instanceof(Sleep);
+ });
+
+ it('should store an array of data', () => {
+ expect(sleep.data.length).to.equal(8);
+ });
+
+ it('should calculate average hours slept', () => {
+ expect(sleep.getAverage("hoursSlept")).to.equal(7.0625);
+ });
+
+ it('should calculate average sleep quality', () => {
+ expect(sleep.getAverage("sleepQuality")).to.equal(3.375);
+ });
+
+ it('should return error if invalid argument is given', () => {
+ expect(sleep.getAverage("Tacos")).to.equal("Tacos is not a valid argument!");
+ });
+
+ it('should retrieve sleep hours data', () => {
+ expect(sleep.getInfoForSpecificDate("2023/03/24", "hoursSlept")).to.equal(9.6);
+ });
+
+ it('should retrieve sleep quality data', () => {
+ expect(sleep.getInfoForSpecificDate("2023/03/24", "sleepQuality")).to.equal(4.3);
+ });
+
+ it('should return an error if date is not available', () => {
+ expect(sleep.getInfoForSpecificDate("1889/04/25", "sleepQuality")).to.equal("There is no data for this date");
+ });
+
+ it('should retrieve sleep hours for specified week', () => {
+ expect(sleep.getInfoForPastWeek("hoursSlept")).to.deep.equal([ 7.8, 6.4, 6.7, 6.4, 8.2, 5.1, 6.3 ]);
+ });
+
+ it('should retrieve sleep quality for specified week', () => {
+ expect(sleep.getInfoForPastWeek("sleepQuality")).to.deep.equal([ 4.1, 4.7, 2, 1, 3.4, 4.2, 3.3 ]);
+ });
+
+ it('should return error if invalid argument is given', () => {
+ expect(sleep.getAverage("ice cream")).to.equal("ice cream is not a valid argument!");
+ });
+});
\ No newline at end of file
diff --git a/test/User-test.js b/test/User-test.js
new file mode 100644
index 0000000000..ad855bfff4
--- /dev/null
+++ b/test/User-test.js
@@ -0,0 +1,73 @@
+import { expect } from 'chai';
+import User from '../src/User';
+import Sleep from '../src/Sleep';
+import Hydration from '../src/Hydration';
+import Activity from '../src/Activity';
+import userTestData from '../src/data/user-test-data.js';
+import activityTestData from '../src/data/activity-test-data.js';
+import hydrationTestData from '../src/data/hydration-test-data';
+import sleepTestData from '../src/data/sleep-test-data';
+
+describe('User', () => {
+ let testUser,
+ hydration,
+ sleep,
+ activity,
+ testUser2;
+ beforeEach(() => {
+ testUser = new User(userTestData.userTestData[0]);
+
+ hydration = new Hydration(hydrationTestData.hydrationTestData);
+ sleep = new Sleep(sleepTestData.sleepTestData);
+ activity = new Activity(activityTestData.activityTestData, testUser.strideLength);
+
+ testUser.hydrationData = hydration;
+ testUser.sleepData = sleep;
+ testUser.activityData = activity;
+
+ testUser2 = new User({});
+ });
+
+ it('should be a function', () => {
+ expect(User).to.be.a('function');
+ });
+
+ it('should set all the properties using setData()', () => {
+ expect(testUser.id).to.equal(1);
+ expect(testUser.name).to.equal("Trystan Gorczany");
+ expect(testUser.address).to.equal("9484 Lucas Flat, West Kittymouth WA 67504");
+ expect(testUser.email).to.equal("Taurean_Pollich31@gmail.com");
+ expect(testUser.strideLength).to.equal(4);
+ expect(testUser.dailyStepGoal).to.equal(7000);
+ expect(testUser.friends).to.deep.equal([ 5, 43, 46, 11 ]);
+ });
+
+ it('should store hydration data', () => {
+ expect(testUser.hydrationData).to.deep.equal(hydration);
+ expect(testUser.hydrationData.data.length).to.equal(8);
+ });
+
+ it('should store sleep data', () => {
+ expect(testUser.sleepData).to.deep.equal(sleep);
+ expect(testUser.sleepData.data.length).to.equal(64);
+ });
+
+ it('should store activity data', () => {
+ expect(testUser.activityData).to.deep.equal(activity);
+ expect(testUser.activityData.data.length).to.equal(8);
+ });
+
+ it('should be able to retun friends friends names', () => {
+ expect(testUser.getFriends(userTestData.userTestData)).to.deep.equal(["Brycen"]);
+ expect(testUser2.getFriends(userTestData.userTestData)).to.equal("Embrace the Solitude");
+ });
+
+ it('should get the average step goals of all users', () => {
+ expect(testUser.getAverage(userTestData.userTestData)).to.equal(6750);
+ });
+
+ it('should get the users first name', () => {
+ expect(testUser.getName()).to.equal('Trystan');
+ expect(testUser2.getName()).to.equal('User');
+ });
+});
\ No newline at end of file
diff --git a/test/UserRepository-test.js b/test/UserRepository-test.js
deleted file mode 100644
index 5ae11729ad..0000000000
--- a/test/UserRepository-test.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import { expect } from 'chai';
-import UserRepository from '../src/UserRepository';
-
-describe('User Repository', () => {
- it('should be a function', function () {
- expect(UserRepository).to.be.a('function');
- });
-});
\ No newline at end of file
diff --git a/webpack.config.js b/webpack.config.js
index 1f1eb1d034..6e09be097d 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -15,7 +15,7 @@ module.exports = {
"module": {
"rules": [
{
- test: /\.css$/i,
+ test: /\.scss$/i,
use: ['style-loader', 'css-loader', 'sass-loader'],
},
{