Habit Tracker is my final project for CS50's Introduction to Computer Science Course. What can I say, Habit Tracker lets you keep track of your habits π π π
- Landing Page
- Sign up using Facebook, GitHub, Google or create a new account using your email address.
- Create new habit
- Manage your habits - preview, edit or delete your habits
- Keep track of your habits in the Dashboard
- Change your settings
- Customize the app the way you want
- React
- React Query
- React Router
- React Hook Form
- Material UI
- Firebase
- Authentication
- Realtime Database
I learned a lot while building the project and for sure I'm going to learn a lot more while maintaining it. That's why I want to keep track of the challenges that I've had along the way so that I can reference them in the future.
How should I store habit's completion state for each day? Should each habit have an array with the dates when it was performed or should I store dates and each date would keep track of the habits that where performed on that day?
I tried to structure the data so that it is saved and retrieved as easily as possible. To do so I've been following Firebase guidelines and in the end came up with the following data structure:
{
"habits": {
"user-one": {
"habit-one": {
"name": "Reading",
"description": "Read a book for at least 30 min in the morning",
"frequency": [0,1,2,3,4]
}
}
},
"checkmarks": {
"user-one": {
"checkmark-id": {
"habitId": "habit-one",
"date": "2020-11-11",
"value": "completed",
}
}
},
"users": {
"user-one": {
"locale": {
"code": "en-GB"
},
"theme": {
"primaryColor": "blue",
"secondaryColor": "red",
"dark": true
},
"performanceGoal": 80
}
}
}
For quite some time I was using Private and Public routes to prevent an authenticated user from accessing the parts of the app available only for logged in user. It was fine but I wanted to use a different layout for authenticated users (additional sidebar on the left).
I found the perfect solution in a blog post by Kent C. Dodds:
function App() {
const user = useUser();
return user ? <AuthenticatedApp /> : <UnauthenticatedApp />;
}
I've never before implemented this in an app and I really wanted to give it a try. My main goal was to give the user an option to change their locale and language. Although this goal was achieved, the solution is far from ideal. First of all, I think that it would be better to split these two layers. For example in YouTube one can open settings and change either Language or Location.
This project was bootstrapped with Create React App.
In the project directory, you can run:
- npm start
- npm test
- npm run build
- npm run eject
For the detailed description of available scripts see CRA Documentation