diff --git a/client/src/App.jsx b/client/src/App.jsx
index 3130c6e4..4d005a08 100644
--- a/client/src/App.jsx
+++ b/client/src/App.jsx
@@ -9,6 +9,8 @@ import Navbar from './Components/navBar';
import ChatInterface from './Components/chatInterface';
import MoodLogging from './Components/moodLogging';
import MoodLogs from './Components/moodLogs';
+import CheckInForm from './Components/checkInForm';
+import CheckInsList from './Components/checkInsList';
import { CssBaseline, Box } from '@mui/material';
import { UserContext } from './Components/userContext';
@@ -30,6 +32,9 @@ function App() {
} />
} />
} />
+ } />
+ } />
+ } />
diff --git a/client/src/Components/checkInForm.jsx b/client/src/Components/checkInForm.jsx
new file mode 100644
index 00000000..fbf10e98
--- /dev/null
+++ b/client/src/Components/checkInForm.jsx
@@ -0,0 +1,90 @@
+import React, { useState } from 'react';
+import axios from 'axios';
+import PropTypes from 'prop-types';
+import {
+ Button,
+ Checkbox,
+ FormControl,
+ FormControlLabel,
+ InputLabel,
+ MenuItem,
+ Select,
+ TextField,
+ Box,
+ Tooltip,
+ } from '@mui/material';
+
+
+function CheckInForm({ userId, checkInId, update }) {
+ const [checkInTime, setCheckInTime] = useState('');
+ const [frequency, setFrequency] = useState('daily');
+ const [notify, setNotify] = useState(false);
+
+
+ const handleSubmit = async (event) => {
+ event.preventDefault();
+ const url = update ? `/api/checkIn/update/${checkInId}` : '/api/checkIn/schedule';
+ const method = update ? 'patch' : 'post';
+ const data = { user_id: userId, check_in_time: checkInTime, frequency, notify };
+ console.log('Submitting:', data);
+ try {
+ const response = await axios[method](url, data);
+ console.log('Success:', response.data.message);
+ // Optionally reset form or handle next steps
+ } catch (error) {
+ console.error('Error:', error.response?.data || error);
+ }
+ };
+
+return (
+
+ setCheckInTime(e.target.value)}
+ sx={{ marginBottom: 3 }}
+ InputLabelProps={{
+ shrink: true,
+ }}
+ required
+ helperText="Select the date and time for your check-in."
+ />
+
+ Frequency
+
+
+
+
+
+ setNotify(e.target.checked)} color="primary" />}
+ label="Notify me"
+ sx={{ marginBottom: 2 }}
+ />
+
+
+ );
+}
+
+CheckInForm.propTypes = {
+ userId: PropTypes.string.isRequired,
+ checkInId: PropTypes.string,
+ update: PropTypes.bool.isRequired,
+};
+
+export default CheckInForm;
diff --git a/client/src/Components/checkInsList.jsx b/client/src/Components/checkInsList.jsx
new file mode 100644
index 00000000..9b19b03a
--- /dev/null
+++ b/client/src/Components/checkInsList.jsx
@@ -0,0 +1,68 @@
+import React, { useState, useEffect} from 'react';
+import axios from 'axios';
+import { useParams } from 'react-router-dom';
+import { List, ListItem, ListItemText, Paper, Typography } from '@mui/material';
+
+function CheckInsList() {
+ const { userId } = useParams(); // Assuming 'user' has 'userId'
+ const [checkIns, setCheckIns] = useState([]);
+ const [loading, setLoading] = useState(false);
+ const [error, setError] = useState('');
+
+ useEffect(() => {
+ const fetchCheckIns = async () => {
+ if (!userId) {
+ setError('User not logged in');
+ return;
+ }
+ setLoading(true);
+ try {
+ const response = await axios.get(`/api/checkIn/retrieveAll?user_id=${userId}`);
+ console.log("API Response:", response.data); // Confirm what you receive
+
+ // Validate if data is an array and has the correct structure
+ if (Array.isArray(response.data) && response.data.every(item => item._id && item._id.$oid && item.check_in_time && item.check_in_time.$date)) {
+ const formattedCheckIns = response.data.map(checkIn => ({
+ ...checkIn,
+ _id: checkIn._id.$oid,
+ check_in_time: new Date(checkIn.check_in_time.$date).toLocaleString(), // Convert date from MongoDB format to a readable string
+ }));
+ setCheckIns(formattedCheckIns);
+ } else {
+ console.error('Data received is not in expected array format:', response.data);
+ setError('Unexpected data format');
+ }
+ setLoading(false);
+ } catch (err) {
+ console.error("Error during fetch:", err);
+ setError(err.message);
+ setLoading(false);
+ }
+ };
+
+ fetchCheckIns();
+ }, [userId]);
+
+
+ if (!userId) return Please log in to see your check-ins.;
+ if (loading) return Loading...;
+ if (error) return Error: {error};
+
+ return (
+
+ Your Check-Ins
+
+ {checkIns.length > 0 ? checkIns.map(checkIn => (
+
+
+
+ )) : }
+
+
+ );
+}
+
+export default CheckInsList;
diff --git a/client/src/Components/sideBar.jsx b/client/src/Components/sideBar.jsx
index 23887e00..fced6164 100644
--- a/client/src/Components/sideBar.jsx
+++ b/client/src/Components/sideBar.jsx
@@ -4,13 +4,15 @@ import DeckIcon from '@mui/icons-material/Deck';
import InsertEmoticonIcon from '@mui/icons-material/InsertEmoticon'; // Icon for mood logging
import ListAltIcon from '@mui/icons-material/ListAlt'; // Icon for mood logs
import ExitToAppIcon from '@mui/icons-material/ExitToApp';
+import EventAvailableIcon from '@mui/icons-material/EventAvailable';
+import ScheduleIcon from '@mui/icons-material/Schedule';
import { UserContext } from './userContext';
import { NavLink, useLocation } from 'react-router-dom';
const drawerWidth = 230;
function Sidebar() {
- const { logout } = useContext(UserContext);
+ const { logout, user } = useContext(UserContext);
const location = useLocation(); // This hook returns the location object that represents the current URL.
const isActive = (path) => location.pathname === path; // This function checks if the current path is the same as the path passed as an argument.
@@ -40,6 +42,8 @@ function Sidebar() {
{ text: "Mind Chat", icon: , path: "/" },
{ text: "Track Your Vibes", icon: , path: "/user/mood_logging" },
{ text: "Mood Logs", icon: , path: "/user/mood_logs" },
+ { text: "Schedule Check-In", icon: , path: "/user/check_in" }, // New item for check-in page
+ { text: "Check-In Reporting", icon: , path: `/user/check_ins/${user?.userId}` } // Dynamically inserting userId
].map((item) => (
{
useEffect(() => {
const savedUser = localStorage.getItem('user');
if (savedUser) {
+ console.log('Loaded user from storage:', savedUser);
setUser(JSON.parse(savedUser));
}
}, []);
diff --git a/server/routes/checkIn.py b/server/routes/checkIn.py
index 8c2cf6c0..d85e5afe 100644
--- a/server/routes/checkIn.py
+++ b/server/routes/checkIn.py
@@ -1,10 +1,10 @@
-from flask import Blueprint, request, jsonify
+from flask import Blueprint, request, jsonify, current_app,Response
from datetime import datetime, timedelta
from pydantic import ValidationError
from models.check_in import CheckIn, Frequency
from dotenv import load_dotenv
from services.azure_mongodb import MongoDBClient
-from bson import ObjectId
+from bson import ObjectId,json_util
from pymongo import ReturnDocument
from bson.errors import InvalidId
from .scheduler_main import scheduler
@@ -95,6 +95,49 @@ def update_check_in(check_in_id):
except Exception as e:
return jsonify({'error': str(e)}), 500
+@checkIn_routes.get('/checkIn/retrieve/')
+def retrieve_check_in(check_in_id):
+ try:
+ check_in = db.check_ins.find_one({'_id': ObjectId(check_in_id)})
+ if check_in:
+ return jsonify(check_in), 200
+ else:
+ return jsonify({'message': 'Check-in not found'}), 404
+ except InvalidId:
+ return jsonify({'error': 'Invalid check-in ID format'}), 400
+ except Exception as e:
+ return jsonify({'error': str(e)}), 500
+
+@checkIn_routes.delete('/checkIn/delete/')
+def delete_check_in(check_in_id):
+ try:
+ result = db.check_ins.delete_one({'_id': ObjectId(check_in_id)})
+ if result.deleted_count:
+ return jsonify({'message': 'Check-in deleted successfully'}), 200
+ else:
+ return jsonify({'message': 'Check-in not found'}), 404
+ except InvalidId:
+ return jsonify({'error': 'Invalid check-in ID format'}), 400
+ except Exception as e:
+ return jsonify({'error': str(e)}), 500
+
+@checkIn_routes.get('/checkIn/retrieveAll')
+def retrieve_all_check_ins():
+ user_id = request.args.get('user_id')
+ if not user_id:
+ return jsonify({'error': 'User ID is required'}), 400
+
+ try:
+ check_ins = db.check_ins.find({'user_id': user_id})
+ check_ins_list = list(check_ins) # Convert the cursor to a list
+ if check_ins_list:
+ return Response(json_util.dumps(check_ins_list), mimetype='application/json'), 200
+ else:
+ return jsonify({'message': 'No check-ins found for the user'}), 404
+ except Exception as e:
+ current_app.logger.error(f'Error retrieving check-ins: {str(e)}')
+ return jsonify({'error': str(e)}), 500
+
@checkIn_routes.get('/checkIn/missed')
def check_missed_check_ins():