+ // if an onClick prop exists, set a cursor pointer, add a role of button, and make it open to tab nav
+
{type == "data" ? (
{title}
{dataSentence}
{subtitle}
+ ) : type == "progress" ? (
+
+
{title}
+
{subtitle}
+ { progressDays.length > 0 ? (
+ /* div for progress map */
+
+ { progressDays.map(day => (
+
+ ))}
+
+ ) : (
+ // image for empty state - no completed challenges yet
+
+ )}
+
) : (
{title}
diff --git a/src/components/Dashboard/ProgressDay.jsx b/src/components/Dashboard/ProgressDay.jsx
new file mode 100644
index 0000000..d7a61c3
--- /dev/null
+++ b/src/components/Dashboard/ProgressDay.jsx
@@ -0,0 +1,14 @@
+import { FaCircle, FaCircleCheck } from "react-icons/fa6"
+
+export default function ProgressDay({ day }) {
+ return (
+
+
+
Journal
+
+
Day {day}
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/src/components/Dashboard/TaskModal.jsx b/src/components/Dashboard/TaskModal.jsx
index 1e96f06..58f8865 100644
--- a/src/components/Dashboard/TaskModal.jsx
+++ b/src/components/Dashboard/TaskModal.jsx
@@ -1,75 +1,107 @@
import { useEffect, useState } from 'react';
import Button from "../Button";
import { IoClose } from "react-icons/io5";
+import { useNavigate } from 'react-router-dom';
+import { db } from '../../firebase';
+import { doc, updateDoc } from 'firebase/firestore';
-export default function TaskModal({ isOpen, onClose}) {
+export default function TaskModal({ isOpen, onClose, user}) {
+ console.log('task modal is open', isOpen);
+ const navigate = useNavigate();
const [selectedTask, setSelectedTask] = useState([]);
- // log the selectedTask after the array changes to update automatically
- useEffect(() => {
+ // log the selectedTask after the array changes to update automatically
+ useEffect(() => {
console.log('Updated Tasks:', selectedTask);
}, [selectedTask]);
function toggleTask(challenge) {
// if the clicked challenge is not selectedTask, setSelectedTask
- if (!selectedTask.includes(challenge)) {
- // log the selection
- console.log(`${challenge} button selected!`);
- setSelectedTask([...selectedTask, challenge]);
- // if the clicked challenge is already in selectedTask, filter it out of selectedTask
- } else {
- // log the deselection
- console.log(`${challenge} button deselected!`);
- setSelectedTask(selectedTask.filter(item => item !== challenge));
+ if (!selectedTask.includes(challenge)) {
+ // log the selection
+ console.log(`${challenge} button selected!`);
+ setSelectedTask([...selectedTask, challenge]);
+ // if the clicked challenge is already in selectedTask, filter it out of selectedTask
+ } else {
+ // log the deselection
+ console.log(`${challenge} button deselected!`);
+ setSelectedTask(selectedTask.filter(item => item !== challenge));
+ }
+ }
+
+ // function to save selected tasks to firestore and local storage
+ async function saveTasks(){
+ if (!user){
+ console.log('User not authenticated yet')
+ return;
+ }
+ const userDocRef = doc(db, "users", user.uid);
+ try {
+ await updateDoc(userDocRef, {
+ challengesSelected: selectedTask
+ });
+
+ console.log("User saved these tasks:", selectedTask);
+
+ // then route to the challenges page
+ navigate("/challenges");
+ } catch (error) {
+ console.error("Error while saving user tasks to firestore", error);
+ console.log("Error sending tasks to database");
+ }
}
- }
if (!isOpen) return null;
return (
-
-
+
+
-
Detox Challenge Options
+
Detox Challenge Options
{/* buttons */}
-
+
-
+
);
diff --git a/src/firebase.js b/src/firebase.js
index 088faf2..a33ba6f 100644
--- a/src/firebase.js
+++ b/src/firebase.js
@@ -1,7 +1,7 @@
// Import the functions you need from the SDKs you need
import { initializeApp } from 'firebase/app';
import { getFirestore } from 'firebase/firestore';
-import { getAuth } from 'firebase/auth';
+import { browserLocalPersistence, getAuth, setPersistence } from 'firebase/auth';
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries
@@ -19,6 +19,7 @@ const firebaseConfig = {
// Initialize Firebase
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
+setPersistence(auth, browserLocalPersistence);
// Initialize Cloud Firestore and get a reference to the service
const db = getFirestore(app);
export { db, auth };
diff --git a/src/pages/Dashboard.jsx b/src/pages/Dashboard.jsx
index 4b10d49..9e5e6dd 100644
--- a/src/pages/Dashboard.jsx
+++ b/src/pages/Dashboard.jsx
@@ -1,76 +1,161 @@
-import { useState } from "react";
+import { useEffect, useState } from "react";
import Button from "../components/Button";
import DashboardTile from "../components/Dashboard/DashboardTile";
import TaskModal from "../components/Dashboard/TaskModal";
+import { auth, db } from "../firebase";
+import { doc, onSnapshot } from "firebase/firestore";
+import { onAuthStateChanged } from "firebase/auth";
+import { useNavigate } from "react-router-dom";
-let daysCompleted = 0;
-let daysLeft = 30 - daysCompleted;
let loginStreak = 1;
export default function Dashboard() {
+ const [user, setUser] = useState(null);
const [taskModalOpen, setTaskModalOpen] = useState(false);
+ // state for whether tasks have been selected or not from dashboard modal
+ const [hasTasks, setHasTasks] = useState(false);
+ // state for challenge task completed days
+ const [completedDays, setCompletedDays] = useState(0);
+ let daysCompleted = completedDays;
+ let daysLeft = 30 - daysCompleted;
+
+ // define variable for the authenticated user
+ // const user = auth.currentUser;
+
+ // useEffect to ensure the authenticated user loads before dashboard data and state is determined
+ useEffect(() => {
+ console.log("User is loading...")
+ const unsub = onAuthStateChanged(auth, (currentUser) => {
+ setUser(currentUser);
+ console.log('The user has been found')
+ });
+
+ return () => {
+ unsub();
+ }
+ }, []);
+
+ useEffect(() => {
+ console.log("About to load the data from the user...")
+ // dont run anything if the user isn't loaded
+ if (!user) {
+ console.log('user wasnt loaded yet or not found');
+ return;
+ } else {
+ console.log('user found');
+ }
+
+ // define variables
+ const userDocRef = doc(db, "users", user.uid);
+
+ // listen in real-time for changes to the document
+ const unsub = onSnapshot(userDocRef, (userDocSnap) => {
+ console.log('User has already selected these tasks: ', userDocSnap.data().challengesSelected);
+ // check if the document's challengesSelected field is > 0 to display the full dashboard and update state
+ if (userDocSnap.exists() && userDocSnap.data().challengesSelected.length > 0){
+ setHasTasks(true);
+ } else {
+ setHasTasks(false);
+ console.log('user hasnt selected any tasks or deselected')
+ }
+
+ // check the document's completedDays for the challenges to update state - add optional chaining in case thee user hasn't started any challenges yet
+ if (userDocSnap.data().journalProgress?.completedDays > 0){
+ setCompletedDays(userDocSnap.data().journalProgress.completedDays);
+ } else {
+ console.log('No days completed yet')
+ setCompletedDays(0);
+ };
+ });
+
+ // call this function once u exit so it stops looking for the changes in the database
+ return () => {
+ unsub();
+ }
+ }, [user]);
+
+ // define variable for a progress day array showing 3 most recent completed tasks, filter numbers over 0 for empty state
+ let progressArray = [completedDays, completedDays - 1, completedDays - 2].filter(num => num > 0);
+ console.log("Progress array:", progressArray);
+
+ // logic to click tile and navigate to community
+ let navigate = useNavigate();
return (
{/* title and button */}
-
-
Welcome Back!
+
+
+ {/* conditional render for new user vs returning */}
+ {hasTasks ? 'Welcome Back!' : 'Welcome New User!'}
+