Skip to content
This repository has been archived by the owner on Jan 17, 2024. It is now read-only.

Commit

Permalink
Merge pull request #26 from mfdavies/patient-login
Browse files Browse the repository at this point in the history
add practioner id to login link
  • Loading branch information
owencooke authored Jan 7, 2024
2 parents 570b03c + 1afb92c commit 157d96c
Show file tree
Hide file tree
Showing 6 changed files with 289 additions and 283 deletions.
30 changes: 15 additions & 15 deletions backend/server/src/constants.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
# Patient login email content
EMAIL_SUBJECT = "MobilityMate Account Access"
EMAIL_BODY_TEMPLATE = """Dear {name},
Welcome to MobilityMate - your dedicated partner in staying active and healthy! 🌟
To access your personalized exercise account and stay up to date with exercises recommended by your practitioner, simply click on the link below:
🔗 https://mobilitymate-a8b53.web.app/patient/{uid}
Your well-being is our priority! If you have any questions or need support, our team is here to assist you every step of the way.
Stay active, stay healthy!
The MobilityMate Team 🏋️‍♂️
"""
# Patient login email content
EMAIL_SUBJECT = "MobilityMate Account Access"
EMAIL_BODY_TEMPLATE = """Dear {name},
Welcome to MobilityMate - your dedicated partner in staying active and healthy! 🌟
To access your personalized exercise account and stay up to date with exercises recommended by your practitioner, simply click on the link below:
🔗 https://mobilitymate-a8b53.web.app/{practitionId}/patient/{patientId}
Your well-being is our priority! If you have any questions or need support, our team is here to assist you every step of the way.
Stay active, stay healthy!
The MobilityMate Team 🏋️‍♂️
"""
175 changes: 89 additions & 86 deletions backend/server/src/main.py
Original file line number Diff line number Diff line change
@@ -1,86 +1,89 @@
from flask import Flask, request, jsonify, render_template
from flask_mail import Mail, Message
from dotenv import load_dotenv
import os
from constants import *
import time
import firebase_admin
from firebase_admin import credentials
from flask_cors import CORS

load_dotenv()
app = Flask(__name__)
app.secret_key = os.getenv("SECRET_KEY")


def create_service_dict():
variables_keys = {
"type": os.getenv("TYPE"),
"project_id": os.getenv("PROJECT_ID"),
"private_key_id": os.getenv("PRIVATE_KEY_ID"),
"private_key": os.getenv("PRIVATE_KEY"),
"client_email": os.getenv("CLIENT_EMAIL"),
"client_id": os.getenv("CLIENT_ID"),
"auth_uri": os.getenv("AUTH_URI"),
"token_uri": os.getenv("TOKEN_URI"),
"auth_provider_x509_cert_url": os.getenv("AUTH_PROVIDER_X509_CERT_URL"),
"client_x509_cert_url": os.getenv("CLIENT_X509_CERT_URL"),
"universe_domain": os.getenv("UNIVERSE_DOMAIN"),
}
return variables_keys


cred = credentials.Certificate(create_service_dict())
firebase_admin.initialize_app(cred)

from conversation.views import conversation_blueprint

# Register the conversation Blueprint
app.register_blueprint(conversation_blueprint, url_prefix="/conversation")
CORS(app)

# Load Flask-Mail config from .env
app.config["MAIL_SERVER"] = os.getenv("MAIL_SERVER")
app.config["MAIL_PORT"] = int(os.getenv("MAIL_PORT"))
app.config["MAIL_USE_TLS"] = os.getenv("MAIL_USE_TLS").lower() == "true"
app.config["MAIL_USERNAME"] = os.getenv("MAIL_USERNAME")
app.config["MAIL_PASSWORD"] = os.getenv("MAIL_PASSWORD")
app.config["MAIL_DEFAULT_SENDER"] = os.getenv("MAIL_DEFAULT_SENDER")
mail = Mail(app)


@app.route("/patient/send-link", methods=["POST"])
def send_link():
try:
data = request.get_json()
uid = data.get("uid")
name = data.get("name")
email = data.get("email")

# Send patient email with login link
message = Message(
subject=EMAIL_SUBJECT,
recipients=[email],
body=EMAIL_BODY_TEMPLATE.format(name=name, uid=uid),
)
mail.send(message)

return jsonify({"success": True, "message": "Email sent successfully"})

except Exception as e:
return jsonify({"success": False, "error": str(e)}), 500


def format_server_time():
server_time = time.localtime()
return time.strftime("%I:%M:%S %p", server_time)


@app.route("/")
def index():
context = {"server_time": format_server_time()}
return render_template("index.html", context=context)


if __name__ == "__main__":
app.run(debug=True, port=os.getenv("PORT", default=5000))
from flask import Flask, request, jsonify, render_template
from flask_mail import Mail, Message
from dotenv import load_dotenv
import os
from constants import *
import time
import firebase_admin
from firebase_admin import credentials
from flask_cors import CORS

load_dotenv()
app = Flask(__name__)
app.secret_key = os.getenv("SECRET_KEY")


def create_service_dict():
variables_keys = {
"type": os.getenv("TYPE"),
"project_id": os.getenv("PROJECT_ID"),
"private_key_id": os.getenv("PRIVATE_KEY_ID"),
"private_key": os.getenv("PRIVATE_KEY"),
"client_email": os.getenv("CLIENT_EMAIL"),
"client_id": os.getenv("CLIENT_ID"),
"auth_uri": os.getenv("AUTH_URI"),
"token_uri": os.getenv("TOKEN_URI"),
"auth_provider_x509_cert_url": os.getenv("AUTH_PROVIDER_X509_CERT_URL"),
"client_x509_cert_url": os.getenv("CLIENT_X509_CERT_URL"),
"universe_domain": os.getenv("UNIVERSE_DOMAIN"),
}
return variables_keys


cred = credentials.Certificate(create_service_dict())
firebase_admin.initialize_app(cred)

from conversation.views import conversation_blueprint

# Register the conversation Blueprint
app.register_blueprint(conversation_blueprint, url_prefix="/conversation")
CORS(app)

# Load Flask-Mail config from .env
app.config["MAIL_SERVER"] = os.getenv("MAIL_SERVER")
app.config["MAIL_PORT"] = int(os.getenv("MAIL_PORT"))
app.config["MAIL_USE_TLS"] = os.getenv("MAIL_USE_TLS").lower() == "true"
app.config["MAIL_USERNAME"] = os.getenv("MAIL_USERNAME")
app.config["MAIL_PASSWORD"] = os.getenv("MAIL_PASSWORD")
app.config["MAIL_DEFAULT_SENDER"] = os.getenv("MAIL_DEFAULT_SENDER")
mail = Mail(app)


@app.route("/patient/send-link", methods=["POST"])
def send_link():
try:
data = request.get_json()
practitionId = data.get("practitionId")
patientId = data.get("patientId")
name = data.get("name")
email = data.get("email")

# Send patient email with login link
message = Message(
subject=EMAIL_SUBJECT,
recipients=[email],
body=EMAIL_BODY_TEMPLATE.format(
name=name, practitionId=practitionId, patientId=patientId
),
)
mail.send(message)

return jsonify({"success": True, "message": "Email sent successfully"})

except Exception as e:
return jsonify({"success": False, "error": str(e)}), 500


def format_server_time():
server_time = time.localtime()
return time.strftime("%I:%M:%S %p", server_time)


@app.route("/")
def index():
context = {"server_time": format_server_time()}
return render_template("index.html", context=context)


if __name__ == "__main__":
app.run(debug=True, port=os.getenv("PORT", default=5000))
55 changes: 29 additions & 26 deletions frontend/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
import { BrowserRouter, Routes, Route } from "react-router-dom";

import Landing from "./views/landing/Landing";
import PatientHome from "./views/patient/PatientHome";
import PractitionerDashboard from "./views/practitioner/PractitionerDashboard";
import PractitionerSignUp from "./views/practitioner/PractitionerSignUp";
import PractitionerLogin from "./views/practitioner/PractitionerLogin";

const App = () => {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Landing />} />
<Route path="/patient/:patientID" element={<PatientHome />} />
<Route
path="/practitioner/dashboard"
element={<PractitionerDashboard />}
/>
<Route path="/practitioner/signUp" element={<PractitionerSignUp />} />
<Route path="/practitioner/login" element={<PractitionerLogin />} />
</Routes>
</BrowserRouter>
);
};

export default App;
import { BrowserRouter, Routes, Route } from "react-router-dom";

import Landing from "./views/landing/Landing";
import PatientHome from "./views/patient/PatientHome";
import PractitionerDashboard from "./views/practitioner/PractitionerDashboard";
import PractitionerSignUp from "./views/practitioner/PractitionerSignUp";
import PractitionerLogin from "./views/practitioner/PractitionerLogin";

const App = () => {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Landing />} />
<Route
path="/:practitionerID/patient/:patientID"
element={<PatientHome />}
/>
<Route
path="/practitioner/dashboard"
element={<PractitionerDashboard />}
/>
<Route path="/practitioner/signUp" element={<PractitionerSignUp />} />
<Route path="/practitioner/login" element={<PractitionerLogin />} />
</Routes>
</BrowserRouter>
);
};

export default App;
46 changes: 23 additions & 23 deletions frontend/src/views/patient/PatientHome.jsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import Navbar from './components/Navbar';
import Exercises from './components/Exercises';
import './styles.css';
import { useState, useEffect, useCallback } from 'react';
import VoiceAI from './components/VoiceAI';
import axios from 'axios';
import Skeleton from './components/Skeleton';
import Navbar from "./components/Navbar";
import Exercises from "./components/Exercises";
import "./styles.css";
import { useState, useEffect, useCallback } from "react";
import VoiceAI from "./components/VoiceAI";
import axios from "axios";
import Skeleton from "./components/Skeleton";
import apiUrl from "../../config";
import { LogOut } from 'lucide-react';
import { useNavigate } from 'react-router-dom';
import { LogOut } from "lucide-react";
import { useNavigate } from "react-router-dom";

const PatientHome = () => {
const navigate = useNavigate();
const [convo, setConvo] = useState({
user: null,
gpt: null,
});
const [userInput, setUserInput] = useState('');
const [userInput, setUserInput] = useState("");

const handleInputChange = (e) => {
setUserInput(e.target.value);
Expand All @@ -26,8 +26,8 @@ const PatientHome = () => {
setConvo((prevConvo) => ({ ...prevConvo, gpt: null }));
updateUserMessage(userInput);
const queryParams = new URLSearchParams({
patient: 'demo',
practitioner: 'demo',
patient: "demo",
practitioner: "demo",
});
try {
const response = await axios.post(
Expand All @@ -42,9 +42,9 @@ const PatientHome = () => {
return prevConvo;
});
} catch (error) {
console.error('Error fetching conversation start:', error);
console.error("Error fetching conversation start:", error);
}
setUserInput('');
setUserInput("");
};

const updateUserMessage = useCallback((newMessage) => {
Expand All @@ -58,8 +58,8 @@ const PatientHome = () => {
useEffect(() => {
const startConversation = async () => {
const queryParams = new URLSearchParams({
patient: 'demo',
practitioner: 'demo',
patient: "demo",
practitioner: "demo",
});
try {
const response = await axios.get(
Expand All @@ -72,7 +72,7 @@ const PatientHome = () => {
return prevConvo;
});
} catch (error) {
console.error('Error fetching conversation start:', error);
console.error("Error fetching conversation start:", error);
}
};
startConversation();
Expand All @@ -86,14 +86,14 @@ const PatientHome = () => {
{
// TODO: what are thooooose
params: new URLSearchParams({
patient: 'demo',
practitioner: 'demo',
patient: "demo",
practitioner: "demo",
}),
}
);
navigate('/');
navigate("/");
} catch (error) {
console.error('Error ending conversation:', error);
console.error("Error ending conversation:", error);
}
};

Expand All @@ -111,7 +111,7 @@ const PatientHome = () => {
</div>
<button
onClick={handleEndSession}
className="flex items-center gap-2 btn btn-ghost"
className="flex items-center gap-2 btn btn-active btn-glass"
>
Done for the day?
<LogOut size={18} />
Expand All @@ -137,7 +137,7 @@ const PatientHome = () => {
</div>
<div className="border-l-[1px] -my-2"></div>
<div className="w-1/3 h-full flex flex-col gap-4 justify-center items-center">
<h3 className='text-lg ml-3'>Exercises</h3>
<h3 className="text-lg ml-3">Exercises</h3>
<Exercises />
</div>
</div>
Expand Down
Loading

0 comments on commit 157d96c

Please sign in to comment.