Skip to content

Commit

Permalink
Feature/Lightmode toggle (#90)
Browse files Browse the repository at this point in the history
* setting up react routes and login/sign up page

* adding login auth

* fixing login and singup popups

* adding log out functionality

* Delete server/.env

* adding lightmode toggle

* adding more lightmode for new components

* fixing white background
  • Loading branch information
clen678 authored Oct 7, 2024
1 parent d272fb4 commit 0a19bf0
Show file tree
Hide file tree
Showing 29 changed files with 1,157 additions and 186 deletions.
275 changes: 200 additions & 75 deletions fitness_tracker/package-lock.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion fitness_tracker/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"@material/tab": "^14.0.0",
"@material/tabs": "^2.3.0",
"@mui/icons-material": "^6.1.2",
"@mui/material": "^5.16.7",
"@mui/material": "^6.1.2",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
Expand All @@ -19,6 +19,7 @@
"prop-types": "^15.8.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-icons": "^5.3.0",
"react-mobile-picker": "^1.0.0",
"react-router-dom": "^6.26.2",
"react-scripts": "5.0.1",
Expand Down
26 changes: 26 additions & 0 deletions fitness_tracker/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@
.App {
text-align: center;
background-color: var(--primary-bg-color);
transition: background-color 0.3s ease-in-out, color 0.3s ease-in-out;
min-height: 100vh;
}

.App-light {
text-align: center;
background-color: #ececec;
transition: background-color 0.3s ease-in-out, color 0.3s ease-in-out;
min-height: 100vh;
}

.App-logo {
Expand All @@ -27,8 +36,25 @@
color: #F00000;
padding-left: 2%;
padding-right: 2%;
transition: background-color 0.3s ease-in-out, color 0.3s ease-in-out;
}

.App-header-light {
background-color: #ffffff;
min-height: 8vh;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
font-size: calc(12px + 2vmin);
font-weight: bold;
color: #F00000;
padding-left: 2%;
padding-right: 2%;
transition: background-color 0.3s ease-in-out, color 0.3s ease-in-out;
}


.App-link {
color: #61dafb;
}
Expand Down
15 changes: 15 additions & 0 deletions fitness_tracker/src/components/DashboardLightmode.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { MdSunny } from "react-icons/md";
import { IoMoon } from "react-icons/io5";
import "../module_CSS/Darkmode.css";

const DashboardLightmode = ({ toggleDarkmode, darkmode }) => {

return (
<div className="darkMode" onClick={toggleDarkmode}>
<MdSunny className={`icon ${darkmode ? 'hide' : 'show'}`} />
<IoMoon className={`icon ${darkmode ? 'show' : 'hide'}`} />
</div>
);
}

export default DashboardLightmode;
26 changes: 17 additions & 9 deletions fitness_tracker/src/components/ExerciseAdder.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import buttons from '../module_CSS/buttons.module.css';
import styles from '../module_CSS/ExerciseLogger.module.css';
import { MenuItem, Select, Tooltip } from '@mui/material';

const ExerciseAdder = ({ exerciseList, addExercise, cancelAddExercise }) => {
const ExerciseAdder = ({ exerciseList, addExercise, cancelAddExercise, darkmode }) => {
const [selectedExercise, setSelectedExercise] = useState(exerciseList.length > 0 ? exerciseList[0] : { name: "No exercises added" });

return (
Expand All @@ -17,16 +17,20 @@ const ExerciseAdder = ({ exerciseList, addExercise, cancelAddExercise }) => {
sx={{
width: "100%",
color: "white",
border: "1px solid white",
border: darkmode ? "1px solid white" : "2px solid #333",
transition: "background-color 0.3s ease-in-out, color 0.3s ease-in-out",
'& .MuiOutlinedInput-notchedOutline': {
borderColor: 'white',
},
'&:hover .MuiOutlinedInput-notchedOutline': {
borderColor: 'white',
},
'& .MuiSvgIcon-root': {
color: 'white',
}
color: darkmode ? 'white' : '#333',
},
'&.Mui-focused .MuiOutlinedInput-notchedOutline': {
borderColor: 'transparent',
},
}}
readOnly // Disable dropdown functionality when no exercises
>
Expand All @@ -41,17 +45,21 @@ const ExerciseAdder = ({ exerciseList, addExercise, cancelAddExercise }) => {
displayEmpty // Placeholder for exercises
sx={{
width: "100%",
color: "white",
border: "1px solid white",
color: darkmode ? 'white' : '#333',
border: darkmode ? "1px solid white" : "2px solid #333",
transition: "background-color 0.3s ease-in-out, color 0.3s ease-in-out",
'& .MuiOutlinedInput-notchedOutline': {
borderColor: 'white',
},
'&:hover .MuiOutlinedInput-notchedOutline': {
borderColor: 'white',
},
'& .MuiSvgIcon-root': {
color: 'white',
}
color: darkmode ? 'white' : '#333',
},
'&.Mui-focused .MuiOutlinedInput-notchedOutline': {
borderColor: 'transparent',
},
}}
onChange={e => {
setSelectedExercise(exerciseList.find(exercise => exercise.name === e.target.value));
Expand Down Expand Up @@ -98,7 +106,7 @@ const ExerciseAdder = ({ exerciseList, addExercise, cancelAddExercise }) => {
</td>
<td>
<button
className={`${buttons.button} ${styles.addButton}`}
className={darkmode ? `${buttons.button} ${styles.addButton}` : `${buttons.buttonLight} ${styles.logSetButton}`}
onClick={() => addExercise(selectedExercise)}
disabled={exerciseList.length === 0 || selectedExercise.name === "No exercises added"}
>
Expand Down
4 changes: 2 additions & 2 deletions fitness_tracker/src/components/ExerciseLogger.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { Fragment, useState } from "react";
import buttons from '../module_CSS/buttons.module.css'
import styles from '../module_CSS/ExerciseLogger.module.css'

const ExerciseLogger = ({ exercise, handleRemoveExercise, setsLogged, setSetsLogged, index }) => {
const ExerciseLogger = ({ exercise, handleRemoveExercise, setsLogged, setSetsLogged, index, darkmode }) => {
console.log("Sets logged", setsLogged)

const logSet = () => {
Expand All @@ -23,7 +23,7 @@ const ExerciseLogger = ({ exercise, handleRemoveExercise, setsLogged, setSetsLog
<td data-label={"Goal"}>{exercise.setsGoal}</td>
<td data-label={"Sets"}>{setsLogged[index]}</td>
<td><button onClick={() => handleRemoveExercise(exercise)} className={`${buttons.button} ${buttons.editButton}`}>Remove</button></td>
<td><button className={`${buttons.button} ${styles.logSetButton}`} onClick={() => logSet()}>Log Set</button></td>
<td><button className={darkmode ? `${buttons.button} ${styles.logSetButton}` : `${buttons.buttonLight} ${styles.logSetButton}`} onClick={() => logSet()}>Log Set</button></td>
</tr>
</Fragment>
);
Expand Down
14 changes: 7 additions & 7 deletions fitness_tracker/src/components/ExercisesDisplay.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import styles from '../module_CSS/ExercisesDisplay.module.css'
import ExerciseAdder from "./ExerciseAdder"
import axios from "axios"

const ExercisesDisplay = ({ exercises, setExercises }) => {
const ExercisesDisplay = ({ exercises, setExercises, darkmode }) => {

const [exerciseList, setExerciseList] = useState({})
const [addExerciseMode, setAddExerciseMode] = useState(false)
Expand Down Expand Up @@ -90,9 +90,9 @@ const ExercisesDisplay = ({ exercises, setExercises }) => {

return (
<Fragment>
<div className={styles.container}>
<h1 className={styles.h1}>Exercises</h1>
<table className={styles.table}>
<div className={darkmode ? styles.container : styles.containerLight}>
<h1 className={darkmode ? styles.heading : styles.headingLight}>Exercises</h1>
<table className={darkmode ? styles.table : styles.tableLight}>
<thead>
<tr>
<th>Name</th>
Expand All @@ -106,17 +106,17 @@ const ExercisesDisplay = ({ exercises, setExercises }) => {
</thead>
<tbody>
{exercises.map(exercise => (
<ExerciseLogger exercise={exercise} handleRemoveExercise={handleRemoveExercise} setsLogged={setsLogged} setSetsLogged={setSetsLogged} index={exercises.findIndex(e=> e.id === exercise.id)} />
<ExerciseLogger exercise={exercise} handleRemoveExercise={handleRemoveExercise} setsLogged={setsLogged} setSetsLogged={setSetsLogged} index={exercises.findIndex(e=> e.id === exercise.id)} darkmode={darkmode}/>
))
}

{addExerciseMode && <ExerciseAdder exerciseList={exerciseList} addExercise={addExercise} cancelAddExercise={cancelAddExercise}/>}
{addExerciseMode && <ExerciseAdder exerciseList={exerciseList} addExercise={addExercise} cancelAddExercise={cancelAddExercise} darkmode={darkmode}/>}
</tbody>
</table>

<div className={styles.buttonContainer}>
<button className={`${buttons.button} ${buttons.addButton}`} onClick={() => setAddExerciseMode(true)}>Add Exercise</button>
<button className={`${buttons.button} ${styles.logWorkoutButton}`} onClick={() => logWorkout()}>Log Workout</button>
<button className={darkmode ? `${buttons.button} ${styles.logWorkoutButton}` : `${buttons.buttonLight} ${styles.logWorkoutButton}`} onClick={() => logWorkout()}>Log Workout</button>
</div>

</div>
Expand Down
6 changes: 3 additions & 3 deletions fitness_tracker/src/components/GraphDisplay.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ import buttons from '../module_CSS/buttons.module.css'
NOTE: Graph data GET calls are made from this class, hence there are no
parameters passed to this function.
*/
function GraphDisplay() {
function GraphDisplay({ darkmode } ) {
let endDate = dateToString(new Date());
let startDate = new Date();
startDate.setDate(startDate.getDate() - 6);
const [data, setData] = useState(FetchPeriod(startDate, new Date()));

return (
<Fragment>
<div className={styles.graphContainer}>
<GenerateGraph data={data} />
<div className={darkmode ? styles.graphContainer : styles.graphContainerLight}>
<GenerateGraph data={data} darkmode={darkmode}/>

<div className={styles.inputContainer}>
<input id="dateSelector" type="date" max={endDate} className={styles.inputField} />
Expand Down
22 changes: 13 additions & 9 deletions fitness_tracker/src/components/GraphGenerator.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,28 +21,32 @@ import styles from '../module_CSS/GraphGenerator.module.css';
obj: {date: "yyyy-mm-dd", score: num}
E.g.: [{date: "1970-01-01", score: 100}, {date: "1970-01-02", score: 120}]
*/
function GenerateGraph({ data }) {
function GenerateGraph({ data, darkmode }) {
return (
<ResponsiveContainer width="100%" height={300} className={styles.rechartWrapper}>
<ResponsiveContainer width="100%" height={300} className={darkmode ? styles.rechartWrapper : styles.rechartWrapperLight}>
<LineChart data={data}>
<Line
type="monotone"
dataKey="score"
stroke="#E10000"
strokeWidth={2}
dot={{ stroke: "#fff", strokeWidth: 1, r: 4}}
dot={{ stroke: darkmode ? "#fff" : "#4A4A4A", strokeWidth: 1, r: 4 }}
/>
<CartesianGrid className={styles["rechartsCartesianGrid"]}/>
<XAxis dataKey="date" className={styles["recharts-cartesian-axis-tick"]}/>
<YAxis className={styles["recharts-cartesian-axis-tick"]}/>
<CartesianGrid className={darkmode ? styles["rechartsCartesianGrid"] : styles["rechartsCartesianGridLight"]}/>
<XAxis dataKey="date" className={darkmode ? styles["recharts-cartesian-axis-tick"] : styles["recharts-cartesian-axis-tick-light"]}/>
<YAxis className={darkmode ? styles["recharts-cartesian-axis-tick"] : styles["recharts-cartesian-axis-tick-light"]}/>
<Tooltip
contentStyle={{
contentStyle={darkmode ? {
backgroundColor: "#333333", // Dark background for tooltip
borderRadius: "4px",
boxShadow: "0 2px 4px rgba(0, 0, 0, 0.2)"
} : {
backgroundColor: "#fff", // White background for tooltip
borderRadius: "4px",
boxShadow: "0 2px 4px rgba(0, 0, 0, 0.2)",
}}
labelStyle={{ color: "#fff" }} // White text for the date label
itemStyle={{ color: "#fff", fontWeight: "bold" }} // Red text for the score value
labelStyle={darkmode ? { color: "#fff" } : { color: "#4A4A4A" }} // White text for the date label
itemStyle={darkmode ? { color: "#fff", fontWeight: "bold" } : { color: "#4A4A4A", fontWeight: "bold" }} // Red text for the score value
/>
</LineChart>
</ResponsiveContainer>
Expand Down
25 changes: 13 additions & 12 deletions fitness_tracker/src/components/NewRoutineModal.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React, { useState } from 'react';
import styles from '../module_CSS/NewRoutineModal.module.css';
import { formatDate } from '../utils/dateUtils.js'
import { dark } from '@mui/material/styles/createPalette.js';

const NewRoutineModal = ({ onSave, onClose }) => {
const NewRoutineModal = ({ onSave, onClose, darkmode }) => {
const today = new Date();
const formattedDate = formatDate(today); // 14 Aug 2024
var id=-1;
Expand Down Expand Up @@ -35,60 +36,60 @@ const NewRoutineModal = ({ onSave, onClose }) => {
};

return (
<div className={styles.modalContainer}>
<div className={darkmode ? styles.modalContainer : styles.modalContainerLight} >
<h2 className={styles.modalTitle}>Create New Routine</h2>
<input
type="text"
className={styles.inputField}
className={darkmode ? styles.inputField : styles.inputFieldLight}
placeholder="Routine Name"
value={routine.name}
onChange={(e) => setRoutine({ ...routine, name: e.target.value })}
/>
<input
type="text"
className={styles.inputField}
className={darkmode ? styles.inputField : styles.inputFieldLight}
placeholder="Muscle Groups"
value={routine.muscle_group}
onChange={(e) => setRoutine({ ...routine, muscles: e.target.value })}
/>
<p className={styles.dateDisplay}>Date: {routine.date}</p>
<h3>Add Exercises</h3>
{routine.exercises.map((exercise, index) => (
<div key={index} className={styles.exerciseContainer}>
<div key={index} className={darkmode ? styles.exerciseContainer : styles.exerciseContainerLight}>
<input
type="text"
className={styles.inputField}
className={darkmode ? styles.inputField : styles.inputFieldLight}
placeholder="Exercise Name"
value={exercise.name}
onChange={(e) => handleExerciseChange(index, 'name', e.target.value)}
/>

<div className={styles.inputWithSuffix}>
<div className={darkmode ? styles.inputWithSuffix : styles.inputWithSuffixLight}>
<input
type="number"
className={styles.inputField}
className={darkmode ? styles.inputField : styles.inputFieldLight}
placeholder="Sets"
value={exercise.sets}
onChange={(e) => handleExerciseChange(index, 'setsGoal', e.target.value)}
/>
<span className={styles.suffix}>sets</span>
</div>

<div className={styles.inputWithSuffix}>
<div className={darkmode ? styles.inputWithSuffix : styles.inputWithSuffixLight}>
<input
type="number"
className={styles.inputField}
className={darkmode ? styles.inputField : styles.inputFieldLight}
placeholder="Reps"
value={exercise.reps}
onChange={(e) => handleExerciseChange(index, 'reps', e.target.value)}
/>
<span className={styles.suffix}>reps</span>
</div>

<div className={styles.inputWithSuffix}>
<div className={darkmode ? styles.inputWithSuffix : styles.inputWithSuffixLight}>
<input
type="number"
className={styles.inputField}
className={darkmode ? styles.inputField : styles.inputFieldLight}
placeholder="Weight"
value={exercise.weight}
onChange={(e) => handleExerciseChange(index, 'weight', e.target.value)}
Expand Down
Loading

0 comments on commit 0a19bf0

Please sign in to comment.