+ {/* Header component */}
+
+
+
+ {/* Route for the home page, redirects to dashboard if logged in, otherwise shows login component */}
+ : } />
+
+ {/* Route for dashboard and its child routes */}
+ : } >
+ {/* Child routes of dashboard */}
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+
+
+ {/* Route for help page */}
+ } />
+
+ {/* Route for forgot password page */}
+ } />
+
+ {/* Route for registration page */}
+ } />
+
+ {/* Route for contact page */}
+ } />
+
+
+
+ )
+}
diff --git a/Appointment.jsx b/Appointment.jsx
new file mode 100644
index 0000000..543f190
--- /dev/null
+++ b/Appointment.jsx
@@ -0,0 +1,176 @@
+import React, { useState, useEffect } from 'react'; // Importing necessary modules from React
+import { useNavigate } from 'react-router-dom'; // Importing useNavigate hook from react-router-dom
+import { Avatar, Button, CssBaseline, TextField, Container, Box, Typography, Paper } from '@mui/material'; // Importing specific components from Material-UI
+import { ArrowBack as ArrowBackIcon} from '@mui/icons-material'; // Importing ArrowBackIcon from Material-UI icons
+
+// Functional component Appointment
+const Appointment = () => {
+ // State variables to manage appointments, doctor name, date & time, and notes
+ const [appointments, setAppointments] = useState([]); // State variable to store appointments
+ const [doctor, setDoctor] = useState(''); // State variable to store doctor's name
+ const [dateTime, setDateTime] = useState(''); // State variable to store date & time
+ const [notes, setNotes] = useState(''); // State variable to store notes
+
+ const token = localStorage.getItem('jwtToken'); // Retrieving JWT token from localStorage
+ const navigate = useNavigate(); // Initializing useNavigate hook for navigation
+
+ // Fetch appointments from the backend on component mount
+ useEffect(() => {
+ fetchAppointments();
+ }, []);
+
+ // Function to format date
+ const formatDate = (dateString) => {
+ const date = new Date(dateString);
+ const options = { year: 'numeric', month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit' };
+ return date.toLocaleDateString('en-US', options);
+ };
+
+ // Function to fetch appointments from the backend
+ const fetchAppointments = async () => {
+ const response = await fetch('http://127.0.0.1:5000/dashboard/appointments', {
+ method: 'GET',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Authorization': `Bearer ${token}`,
+ }
+ });
+ if (response.ok) {
+ const responseData = await response.json();
+ const { appointments } = responseData.data;
+ setAppointments(appointments);
+ }
+ };
+
+ // Function to record a new appointment
+ const recordAppointment = async () => {
+ const appointment = { doctor, dateTime, notes };
+ const response = await fetch('http://127.0.0.1:5000/dashboard/appointments', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Authorization': `Bearer ${token}`,
+ },
+ body: JSON.stringify(appointment),
+ });
+ if (response.ok) {
+ console.log('Appointment recorded successfully');
+ fetchAppointments(); // Fetch appointments after recording
+ }
+ };
+
+ // Function to delete an appointment
+ const deleteAppointment = async (appointmentId) => {
+ const response = await fetch('http://127.0.0.1:5000/dashboard/appointments', {
+ method: 'DELETE',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Authorization': `Bearer ${token}`,
+ },
+ body: JSON.stringify({ appointment_id: appointmentId }),
+ });
+ if (response.ok) {
+ console.log('Appointment deleted successfully');
+ fetchAppointments(); // Fetch appointments after deletion
+ }
+ };
+
+ // JSX to render the component
+ return (
+
+
+ {/* Button to navigate back to previous page */}
+ }
+ onClick={() => navigate('/')}
+ sx={{ mb: 2, width: '150px', height: '40px' }}
+ >
+ Go Back
+
+
+
+ Appointment Scheduler
+
+ {/* Form to schedule a new appointment */}
+
+ setDateTime(e.target.value)}
+ />
+ setDoctor(e.target.value)}
+ />
+ setNotes(e.target.value)}
+ />
+ {/* Button to schedule the appointment */}
+
+
+
+ {/* Displaying scheduled appointments */}
+ {appointments && (
+
+
+ Scheduled Appointments
+
+ {appointments.map((appointment) => (
+
+
+ {appointment.doctor_name} - {appointment.appointment_notes} at {formatDate(appointment.appointment_date)}
+
+ {/* Button to delete the appointment */}
+
+
+ ))}
+
+ )}
+
+ );
+};
+
+export default Appointment; // Exporting the component
diff --git a/ClickableBox.jsx b/ClickableBox.jsx
new file mode 100644
index 0000000..7cf4d70
--- /dev/null
+++ b/ClickableBox.jsx
@@ -0,0 +1,47 @@
+import React from "react"; // Importing necessary modules from React
+import { Link } from "react-router-dom"; // Importing Link component from react-router-dom
+import { Box, Typography } from "@mui/material"; // Importing Box and Typography components from Material-UI
+
+// Functional component ClickableBox
+const ClickableBox = ({ title, path, icon: Icon }) => {
+ return (
+ // Link component to navigate to the specified path when clicked
+
+ {/* Box component representing the clickable box */}
+
+ {/* Box component to center content vertically and horizontally */}
+
+ {/* Rendering icon if provided */}
+ {Icon && }
+ {/* Rendering title */}
+
+ {title}
+
+
+
+
+ );
+};
+
+export default ClickableBox; // Exporting the component as the default export
diff --git a/Contact.jsx b/Contact.jsx
new file mode 100644
index 0000000..c04774f
--- /dev/null
+++ b/Contact.jsx
@@ -0,0 +1,203 @@
+import React, { useState } from "react"; // Importing necessary modules from React
+import { useNavigate } from "react-router-dom"; // Importing useNavigate hook from react-router-dom
+import {
+ Avatar,
+ Button,
+ CssBaseline,
+ Container,
+ Box,
+ Typography,
+ Link,
+ TextField,
+ Grid,
+} from "@mui/material"; // Importing specific components from Material-UI
+import LocationOnIcon from "@mui/icons-material/LocationOn"; // Importing LocationOnIcon from Material-UI icons
+import PhoneIcon from "@mui/icons-material/Phone"; // Importing PhoneIcon from Material-UI icons
+import EmailIcon from "@mui/icons-material/Email"; // Importing EmailIcon from Material-UI icons
+
+// Functional component Contact
+export default function Contact() {
+ const navigate = useNavigate(); // Initializing useNavigate hook for navigation
+
+ const [responseMessage, setResponseMessage] = useState(''); // State variable to manage response message
+ const [formData, setFormData] = useState({ // State variable to manage form data
+ name: '',
+ email: '',
+ message: '',
+ });
+
+ // Function to handle input change in the form fields
+ const handleInputChange = (e) => {
+ const { name, value } = e.target;
+ setFormData((prevFormData) => ({
+ ...prevFormData,
+ [name]: value,
+ }));
+ };
+
+ // Function to handle form submission
+ const handleSubmit = async (e) => {
+ e.preventDefault();
+ try {
+ const response = await fetch('http://127.0.0.1:5000/services/contact', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(formData),
+ });
+
+ if (response.ok) {
+ const data = await response.json();
+ if (data.status === 'success') {
+ setResponseMessage(data.message);
+ setFormData({
+ email: '',
+ name: '',
+ message: '',
+ });
+ } else {
+ setResponseMessage(data.message);
+ }
+ } else {
+ setErrorMessage('HTTP error: ' + response.status);
+ }
+ } catch (error) {
+ setErrorMessage('An error occurred: ' + error.message + '.');
+ }
+};
+
+ return (
+ // Container component to contain the contact form and information
+
+
+ {/* Grid component to layout the content */}
+
+ {/* Grid item for displaying address and contact information */}
+
+
+ {/* Avatar and Typography components for displaying address */}
+
+
+
+
+ Our Address
+
+
+ 6521 AL Hwy 69 S, Suit N,
+
+ Tuscaloosa, AL 35405
+
+
+ {/* Avatar and Typography components for displaying phone number */}
+
+
+
+
+ Phone
+
+ (866)-919-1246
+
+ {/* Avatar and Typography components for displaying email */}
+
+
+
+
+ Email
+
+ info@aimplusmedicalsupplies.com
+
+ http://www.aimplusmedicalsupplies.com
+
+
+
+ {/* Grid item for contact form */}
+
+
+
+ Send us a Message
+
+ {/* Form for sending a message */}
+
+ {/* Button to navigate back */}
+
+ {/* Displaying response message if any */}
+ {responseMessage && (
+
+ {responseMessage}
+
+ )}
+
+
+
+
+ );
+};
diff --git a/Dashboard.jsx b/Dashboard.jsx
index 4fc41c6..eecc14e 100644
--- a/Dashboard.jsx
+++ b/Dashboard.jsx
@@ -1,5 +1,6 @@
-import React, { useState } from 'react';
-import { styled, createTheme, ThemeProvider } from '@mui/system';
+import React from 'react'; // Importing necessary modules from React
+import { Link, Outlet, useLocation } from 'react-router-dom'; // Importing Link, Outlet, and useLocation from react-router-dom
+import { styled } from '@mui/system'; // Importing styled from MUI system
import {
CssBaseline,
Drawer as MuiDrawer,
@@ -9,124 +10,178 @@ import {
Divider,
IconButton,
Container,
+ ListItemButton,
+ ListItemIcon,
+ ListItemText,
Typography
-} from '@mui/material';
-import ChevronLeftIcon from '@mui/icons-material/ChevronLeft';
-import { mainListItems, secondaryListItems } from './ListItems';
+} from '@mui/material'; // Importing specific components from Material-UI
+import {
+ AccountBox as AccountBoxIcon,
+ EditCalendar as EditCalendarIcon,
+ MedicalServices as MedicalServicesIcon,
+ Print as PrintIcon,
+ EditNote as EditNoteIcon,
+ PriorityHigh as PriorityHighIcon,
+ People as PeopleIcon,
+ Notifications as NotificationsIcon,
+ Assignment as AssignmentIcon,
+ ChevronLeft as ChevronLeftIcon,
+ ChevronRight as ChevronRightIcon
+ } from '@mui/icons-material'; // Importing specific icons from Material-UI icons
+
+import ClickableBox from './ClickableBox'; // Importing ClickableBox component from local file
-const drawerWidth = 250;
+const drawerWidth = 250; // Defining drawer width
-const Drawer = styled(MuiDrawer, { shouldForwardProp: (prop) => prop !== 'open' })(({ theme, open }) => ({
- '& .MuiDrawer-paper': {
- position: 'relative',
- whiteSpace: 'nowrap',
- width: drawerWidth,
- transition: theme.transitions.create('width', {
- easing: theme.transitions.easing.sharp,
- duration: theme.transitions.duration.enteringScreen,
- }),
- boxSizing: 'border-box',
- ...(!open && {
- overflowX: 'hidden',
+// Styling the Drawer component using styled from MUI system
+const Drawer = styled(MuiDrawer, { shouldForwardProp: (prop) => prop !== 'open' })(
+ ({ theme, open }) => ({
+ '& .MuiDrawer-paper': {
+ position: 'relative',
+ whiteSpace: 'nowrap',
+ width: drawerWidth,
transition: theme.transitions.create('width', {
easing: theme.transitions.easing.sharp,
- duration: theme.transitions.duration.leavingScreen,
+ duration: theme.transitions.duration.enteringScreen,
+ }),
+ boxSizing: 'border-box',
+ background: theme.palette.primary.main,
+ ...(!open && {
+ overflowX: 'hidden',
+ transition: theme.transitions.create('width', {
+ easing: theme.transitions.easing.sharp,
+ duration: theme.transitions.duration.leavingScreen,
+ }),
+ width: theme.spacing(7),
+ [theme.breakpoints.up('sm')]: {
+ width: theme.spacing(9),
+ },
}),
- width: theme.spacing(7),
- [theme.breakpoints.up('sm')]: {
- width: theme.spacing(9),
- },
- }),
- },
-}));
+ },
+ }),
+);
-export default function Dashboard() {
- const [open, setOpen] = React.useState(true);
+// Functional component Dashboard
+export default function Dashboard({username}) {
+ const [open, setOpen] = React.useState(false); // State variable to manage drawer open/close
+ const location = useLocation(); // Getting current location using useLocation hook from react-router-dom
+ // Function to toggle drawer open/close
const toggleDrawer = () => {
setOpen(!open);
};
-
-const ClickableBox = ({ title, onClick }) => {
- return (
-
-
-
- {title}
-
-
-
- );
-};
-
-const handleClick = (route) => {
- // You can handle navigation to different routes here
- console.log('Navigating to:', route);
- };
-
+
return (
-
-
-
-
+
+ {/* Drawer component for navigation */}
+
+ {/* Toolbar for drawer */}
+
+ {/* IconButton to toggle drawer */}
+
+ {open ? : }
+
+
+
+ {/* List for navigation links */}
+
+
+ {/* List item for Profile */}
+
+
+
+
+
+ Profile
+
+ }
+ />
+
+ {/* List item for Glucose Logs */}
+
+
+
+
+
+ Glucose Logs
+
+ }
+ />
+
+ {/* List item for Appointments */}
+
+
+
+
+
+ Appointments
+
+ }
+ />
+
+ {/* List item for Notifications */}
+
+
+
+
+
+ Notifications
+
+ }
+ />
+
+
+
+
+
-
-
-
-
-
-
- {mainListItems}
-
- {secondaryListItems}
-
-
-
- theme.palette.mode === 'light'
- ? theme.palette.grey[100]
- : theme.palette.grey[900],
- flexGrow: 1,
- height: '100vh',
- overflow: 'auto',
- }}
- >
-
-
-
- Dashboard
-
-
- handleClick('/glucose')} />
- handleClick('/?')} />
- handleClick('./ListItems')} />
- handleClick('/?')} />
- {/* Add more clickable boxes as needed */}
-
-
-
+ {/* Container for main content */}
+
+ {/* Typography for dashboard title */}
+
+ {username}'s Dashboard
+
+ {/* Conditionally rendering ClickableBox components based on location */}
+ {location.pathname === "/dashboard" && (
+
+
+
+
+
+
+
+
+ )}
+ {/* Rendering nested routes */}
+
+
+
);
- }
\ No newline at end of file
+}
diff --git a/ForgotPassword.jsx b/ForgotPassword.jsx
new file mode 100644
index 0000000..c878c2d
--- /dev/null
+++ b/ForgotPassword.jsx
@@ -0,0 +1,127 @@
+import React, { useState } from 'react'; // Importing necessary modules from React
+import { useNavigate } from 'react-router-dom'; // Importing useNavigate hook from react-router-dom
+import {
+ Avatar,
+ Button,
+ CssBaseline,
+ TextField,
+ Container,
+ Box,
+ Typography,
+ Snackbar, // Importing specific components from Material-UI
+} from '@mui/material'; // Importing necessary components from Material-UI
+import EmailIcon from '@mui/icons-material/Email'; // Importing EmailIcon from Material-UI icons
+
+// Functional component ForgotPassword
+export default function ForgotPassword() {
+ const navigate = useNavigate(); // Getting navigation function using useNavigate hook from react-router-dom
+
+ // State variables for response message and form data
+ const [responseMessage, setResponseMessage] = useState('');
+ const [formData, setFormData] = useState({
+ email: '',
+ });
+
+ // Function to handle input changes in the form
+ const handleInputChange = (e) => {
+ const { name, value } = e.target;
+ setFormData((prevFormData) => ({
+ ...prevFormData,
+ [name]: value,
+ }));
+ };
+
+ // Function to handle form submission
+ const handleSubmit = async (e) => {
+ e.preventDefault();
+ try {
+ const response = await fetch('http://127.0.0.1:5000/auth/forgot-password', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(formData),
+ });
+
+ if (response.ok) {
+ const data = await response.json();
+ if (data.status === 'success') {
+ // Setting response message and resetting form data if successful
+ setResponseMessage(data.message);
+ setFormData({
+ email:'',
+ });
+ } else {
+ // Setting response message if unsuccessful
+ setResponseMessage(data.message);
+ }
+ } else {
+ console.error('HTTP error:', response.status)
+ }
+ } catch (error) {
+ console.error('Error during submission:', error);
+ }
+ };
+
+ return (
+ // Main container for the forgot password form
+
+
+
+ {/* Avatar for the email icon */}
+
+
+
+ {/* Title for the forgot password form */}
+
+ Forgot password? We can help!
+
+ {/* Form for submitting email for password recovery */}
+
+
+ {/* Button to submit the form */}
+
+ {/* Button to navigate back */}
+
+ {/* Display response message */}
+ {responseMessage && (
+
+ {responseMessage}
+
+ )}
+
+
+
+ );
+}
diff --git a/GlucoseLogs.jsx b/GlucoseLogs.jsx
new file mode 100644
index 0000000..d3aace9
--- /dev/null
+++ b/GlucoseLogs.jsx
@@ -0,0 +1,148 @@
+import React, { useState, useEffect } from 'react';
+import { useNavigate } from 'react-router-dom';
+import { Button, CssBaseline, TextField, Container, Box, Typography, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper } from '@mui/material';
+import { ArrowBack as ArrowBackIcon} from '@mui/icons-material';
+
+function GlucoseLogs() {
+ const [dateTime, setDateTime] = useState('');
+ const [glucoseLevel, setGlucoseLevel] = useState('');
+ const [logs, setLogs] = useState([]);
+
+ const token = localStorage.getItem('jwtToken');
+ const navigate = useNavigate();
+
+ useEffect(() => {
+ fetchLogs();
+ }, []);
+
+ const formatDate = (dateString) => {
+ const date = new Date(dateString);
+ const options = { year: 'numeric', month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit' };
+ return date.toLocaleDateString('en-US', options);
+ };
+
+ const fetchLogs = async () => {
+ const response = await fetch('http://127.0.0.1:5000/dashboard/glucose', {
+ method: 'GET',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Authorization': `Bearer ${token}`,
+ }
+ });
+ if (response.ok) {
+ const responseData = await response.json();
+ const { logs } = responseData.data;
+ setLogs(logs);
+ }
+ }
+
+ const recordLog = async () => {
+ const log = { date, time, glucoseLevel };
+ const response = await fetch('/api/glucose', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Authorization': `Bearer ${token}`,
+ },
+ body: JSON.stringify(log),
+ });
+ if (response.ok) {
+ console.log('Log recorded successfully');
+ loadLogs();
+ }
+ };
+
+ const deleteLog = async () => {
+ const response = await fetch('http://127.0.0.1:5000/dashboard/glucose', {
+ method: 'DELETE',
+ headers: {
+ 'Authorization': `Bearer ${token}`,
+ },
+ });
+ if (response.ok) {
+ console.log('Log deleted successfully');
+ loadLogs();
+ }
+ };
+
+ return (
+
+
+ }
+ onClick={() => navigate('/')}
+ sx={{ mb: 2, width: '150px', height: '40px' }}
+ >
+ Go Back
+
+
+
+ Glucose Log Tracker
+
+
+ setDateTime(e.target.value)}
+ />
+ setGlucoseLevel(e.target.value)}
+ />
+
+
+
+ {logs && (
+
+
+ Previous Glucose Logs
+
+ {logs.map((log) => (
+
+
+ {formatDate(log.log_timestamp)}: {log.glucose_level} mg/dL
+
+
+
+ ))}
+
+ )}
+
+ );
+}
+
+export default GlucoseLogs;
diff --git a/Header.jsx b/Header.jsx
new file mode 100644
index 0000000..deb8649
--- /dev/null
+++ b/Header.jsx
@@ -0,0 +1,61 @@
+import React from "react"; // Importing necessary modules from React
+import { Link, useNavigate } from 'react-router-dom'; // Importing Link and useNavigate from react-router-dom
+import { AppBar, Toolbar, Button, IconButton } from '@mui/material'; // Importing necessary components from Material-UI
+import {
+ Help as HelpIcon,
+ ContactMail as ContactIcon,
+ AccountCircle as AccountCircleIcon,
+ Logout as LogoutIcon
+} from '@mui/icons-material'; // Importing necessary icons from Material-UI
+import TitleLogo from '../assets/images/svgs/title-removebg-preview.png'; // Importing company logo
+
+// Styles for buttons
+const buttonStyles = {
+ fontSize: '1.3rem',
+ padding: '15px',
+};
+
+// Functional component Header
+export default function Header({ isLoggedIn, setIsLoggedIn }) {
+ const navigate = useNavigate(); // Getting navigation function using useNavigate hook from react-router-dom
+
+ return (
+ // Header bar with app title and navigation buttons
+
+
+ {/* Company logo */}
+
+
+
+
+ {/* Help button */}
+
+ {/* Contact Us button */}
+
+ {/* Dashboard button */}
+
+ {/* Logout button (visible only when user is logged in) */}
+ {isLoggedIn && (
+
+ )}
+
+
+
+ );
+};
diff --git a/HelpInfo.jsx b/HelpInfo.jsx
new file mode 100644
index 0000000..8767600
--- /dev/null
+++ b/HelpInfo.jsx
@@ -0,0 +1,92 @@
+import React from "react"; // Importing necessary modules from React
+import { useNavigate } from "react-router-dom"; // Importing useNavigate hook from react-router-dom
+import {
+ Avatar,
+ Button,
+ CssBaseline,
+ Container,
+ Box,
+ Typography,
+ Accordion,
+ AccordionSummary,
+ AccordionDetails,
+} from "@mui/material"; // Importing necessary components from Material-UI
+import LiveHelpIcon from "@mui/icons-material/LiveHelp"; // Importing LiveHelpIcon from Material-UI
+import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; // Importing ExpandMoreIcon from Material-UI
+
+// Functional component HelpInfo
+export default function HelpInfo() {
+ const navigate = useNavigate(); // Getting navigation function using useNavigate hook from react-router-dom
+
+ // FAQ data array containing objects with questions and answers
+ const faqData = [
+ {
+ question: "How do I place an order?",
+ answer:
+ "TBI", // To Be Implemented
+ },
+ {
+ question: "How can I track my orders?",
+ answer:
+ "TBI", // To Be Implemented
+ },
+ {
+ question: "How can I update my profile information?",
+ answer:
+ "TBI", // To Be Implemented
+ },
+ ];
+
+ return (
+ // Container for the main content with a fixed width
+
+ {/* Normalizing CSS */}
+ {/* Main content wrapper */}
+
+ {/* Avatar representing help icon */}
+
+
+
+ {/* Title */}
+
+ Questions? How can we help?
+
+ {/* Accordion component for displaying FAQ */}
+
+ {faqData.map((faq, index) => (
+
+ {/* Accordion summary with question */}
+ } // Icon indicating expandable content
+ aria-controls={`panel${index}-content`}
+ id={`panel${index}-header`}
+ >
+ {faq.question}
+
+ {/* Accordion details with answer */}
+
+ {faq.answer}
+
+
+ ))}
+
+ {/* Button to navigate back */}
+
+
+
+ );
+};
diff --git a/Login.jsx b/Login.jsx
new file mode 100644
index 0000000..5058d5f
--- /dev/null
+++ b/Login.jsx
@@ -0,0 +1,178 @@
+import React, { useState } from 'react'; // Importing React and useState hook
+import { useNavigate } from 'react-router-dom'; // Importing useNavigate hook from react-router-dom
+import {
+ Avatar,
+ Button,
+ CssBaseline,
+ TextField,
+ Container,
+ Box,
+ Typography,
+} from '@mui/material'; // Importing necessary components from Material-UI
+import LockOutlinedIcon from '@mui/icons-material/LockOutlined'; // Importing LockOutlinedIcon from Material-UI
+
+// Functional component Login
+export default function Login({ setIsLoggedIn, setUsername }) {
+ const navigate = useNavigate(); // Getting navigation function using useNavigate hook from react-router-dom
+
+ // State variables to store form data and error message
+ const [formData, setFormData] = useState({
+ email: '',
+ password: '',
+ });
+ const [errorMessage, setErrorMessage] = useState('');
+
+ // Function to handle input change and update form data accordingly
+ const handleInputChange = (e) => {
+ const { name, value } = e.target;
+ setFormData((prevFormData) => ({
+ ...prevFormData,
+ [name]: value,
+ }));
+ };
+
+ // Function to handle login form submission
+ const handleLogin = async (e) => {
+ e.preventDefault();
+ // Checking if the email and password match the predefined values
+ if (formData.email === 'user' && formData.password === 'password') {
+ setIsLoggedIn(true); // Setting isLoggedIn state to true
+ }
+ try {
+ // Making a POST request to the login endpoint with form data
+ const response = await fetch('http://127.0.0.1:5000/auth/login', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(formData),
+ });
+
+ if (response.ok) {
+ // If the response is successful, parse the data
+ const data = await response.json();
+ if (data.status === 'success') {
+ localStorage.setItem('jwtToken', data.access_token); // Storing JWT token in local storage
+ setUsername(data.username); // Setting username using setUsername function
+ setIsLoggedIn(true); // Setting isLoggedIn state to true
+ } else {
+ setErrorMessage(data.message); // Setting error message if login is unsuccessful
+ }
+ } else {
+ setErrorMessage('HTTP error: ' + response.status); // Setting error message for HTTP error
+ }
+ } catch (error) {
+ setErrorMessage('An error occurred: ' + error.message + '.'); // Setting error message for general error
+ }
+ };
+
+ return (
+ // Main container for login form
+
+ {/* Normalizing CSS */}
+ {/* Box for arranging components vertically */}
+
+ {/* Avatar representing lock icon */}
+
+
+
+ {/* Title */}
+
+ Welcome!
+
+ {/* Form for login */}
+
+ {/* Text field for email */}
+
+ {/* Text field for password */}
+
+ {/* Error message display */}
+ {errorMessage && (
+
+ {errorMessage}
+
+ )}
+ {/* Button for submitting login form */}
+
+ {/* Button for navigating to forgot password page */}
+
+
+ {/* Link to registration page */}
+
+ navigate('/registration')}
+ >
+ Don't have an account?
+
+
+
+
+ );
+}
diff --git a/MedicalForms.jsx b/MedicalForms.jsx
new file mode 100644
index 0000000..850f44e
--- /dev/null
+++ b/MedicalForms.jsx
@@ -0,0 +1,55 @@
+import React from "react"; // Importing React library
+import { useNavigate } from "react-router-dom"; // Importing useNavigate hook from react-router-dom
+import { Button, Grid, Paper, Typography, Link } from '@mui/material'; // Importing necessary components from Material-UI library
+import ArrowBackIcon from '@mui/icons-material/ArrowBack'; // Importing ArrowBackIcon from Material-UI
+
+// Importing PDF files from the assets folder
+import AIMMedicaidCommercialCMN from '../assets/PDF/AIM-Medicaid_Commericial-CMN-11_23.pdf';
+import AIMMedicareCMN from '../assets/PDF/AIM-Medicare-CMN-5_9_23.pdf';
+
+// Functional component MedicalForms
+const MedicalForms = () => {
+ const navigate = useNavigate(); // Getting navigation function using useNavigate hook from react-router-dom
+
+ // Array of documents with their names and paths
+ const documents = [
+ { name: 'AIM Plus Medicaid Commericial CMN', docPath: AIMMedicaidCommercialCMN },
+ { name: 'AIM Plus Medicare CMN', docPath: AIMMedicareCMN },
+ ];
+
+ return (
+
+ {/* Button to navigate back */}
+ } // Icon for back arrow
+ onClick={() => navigate('/')} // Click event to navigate back to home
+ sx={{ mb: 2, width: '150px', height: '40px' }} // Custom styles for button
+ >
+ Go Back
+
+ {/* Title for the page */}
+
+ Medical Forms
+
+ {/* Grid container to display documents */}
+
+ {documents.map((doc, index) => (
+
+ {/* Paper component to display each document */}
+
+ {doc.name} {/* Document name */}
+ {/* Link to open the PDF document in a new tab */}
+
+ Open PDF
+
+
+
+ ))}
+
+
+ );
+};
+
+export default MedicalForms; // Exporting MedicalForms component
diff --git a/Notifications.jsx b/Notifications.jsx
new file mode 100644
index 0000000..73f094c
--- /dev/null
+++ b/Notifications.jsx
@@ -0,0 +1,78 @@
+import React, { useState, useEffect } from 'react'; // Importing necessary modules from React
+import { useNavigate } from 'react-router-dom'; // Importing useNavigate hook from react-router-dom
+import { Typography, Paper, Box, Button } from '@mui/material'; // Importing necessary components from Material-UI
+import { ArrowBack as ArrowBackIcon } from '@mui/icons-material'; // Importing ArrowBackIcon from Material-UI
+
+// Functional component Notifications
+const Notifications = () => {
+ const [notifications, setNotifications] = useState([]); // State to store notifications
+ const token = localStorage.getItem('jwtToken'); // Retrieving JWT token from local storage
+ const navigate = useNavigate(); // Getting navigation function using useNavigate hook from react-router-dom
+
+ // useEffect hook to fetch notifications when the component mounts
+ useEffect(() => {
+ fetchNotifications();
+ }, []);
+
+ // Function to format date string
+ const formatDate = (dateString) => {
+ const date = new Date(dateString);
+ const options = { year: 'numeric', month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit' };
+ return date.toLocaleDateString('en-US', options);
+ };
+
+ // Function to fetch notifications from the backend
+ const fetchNotifications = async () => {
+ const response = await fetch('http://127.0.0.1:5000/dashboard/notifications', {
+ method: 'GET',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Authorization': `Bearer ${token}`, // Sending JWT token in the request headers for authentication
+ }
+ });
+ if (response.ok) {
+ const responseData = await response.json();
+ const { notifications } = responseData.data;
+ setNotifications(notifications); // Updating notifications state with the fetched data
+ }
+ };
+
+ return (
+
+ {/* Button to navigate back */}
+ } // Icon for back arrow
+ onClick={() => navigate('/')} // Click event to navigate back to home
+ sx={{ mb: 2, width: '150px', height: '40px' }} // Custom styles for button
+ >
+ Go Back
+
+ {/* Title for the page */}
+
+ Notifications
+
+ {/* Displaying notifications in a Paper component */}
+ {notifications && (
+
+ {/* Mapping through notifications array and displaying each notification */}
+ {notifications.map((notification) => (
+
+ {/* Displaying formatted date and notification content */}
+
+ {formatDate(notification.status_timestamp)}: {notification.notification}
+
+ {/* Button to delete notification */}
+
+
+ ))}
+
+ )}
+
+ );
+};
+
+export default Notifications; // Exporting Notifications component
diff --git a/Profile.jsx b/Profile.jsx
new file mode 100644
index 0000000..7bb1900
--- /dev/null
+++ b/Profile.jsx
@@ -0,0 +1,149 @@
+import React, { useState, useEffect } from 'react'; // Importing necessary modules from React
+import { TextField, Button, Typography, Box, CssBaseline, Paper, Container } from '@mui/material'; // Importing necessary components from Material-UI
+import { ArrowBack as ArrowBackIcon } from '@mui/icons-material'; // Importing ArrowBackIcon from Material-UI
+import { useNavigate } from 'react-router-dom'; // Importing useNavigate hook from react-router-dom
+
+// Functional component ProfilePage
+const ProfilePage = () => {
+ const [editing, setEditing] = useState(false); // State to manage editing mode
+ const [errorMessage, setErrorMessage] = useState(''); // State to manage error messages
+ const [profileInfo, setProfileInfo] = useState({ // State to store profile information
+ first_name: '',
+ last_name: '',
+ dob: '',
+ primary_phone: '',
+ secondary_phone: '',
+ address: '',
+ primary_insurance: '',
+ id_number: '',
+ contact_person: '',
+ doctor_name: '',
+ doctor_phone: '',
+ doctor_fax: '',
+ });
+ const token = localStorage.getItem('jwtToken'); // Getting JWT token from local storage
+ const navigate = useNavigate(); // Getting navigation function using useNavigate hook from react-router-dom
+
+ // useEffect hook to fetch profile information when the component mounts
+ useEffect(() => {
+ fetchProfile();
+ }, []);
+
+ // Function to handle editing mode
+ const handleEdit = () => {
+ setEditing(true);
+ };
+
+ // Function to save changes and exit editing mode
+ const handleSave = () => {
+ setEditing(false);
+ };
+
+ // Function to handle changes in input fields
+ const handleChange = (e) => {
+ const { name, value } = e.target;
+ setProfileInfo({ ...profileInfo, [name]: value });
+ };
+
+ // Function to fetch profile information from the backend
+ const fetchProfile = async () => {
+ try {
+ const response = await fetch('http://127.0.0.1:5000/dashboard/profile', {
+ method: 'GET',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Authorization': `Bearer ${token}`,
+ },
+ });
+
+ if (response.ok) {
+ const dataBody = await response.json();
+ if (dataBody.status === 'success') {
+ setProfileInfo(dataBody.data); // Updating profileInfo state with fetched data
+ } else {
+ setErrorMessage(data.message);
+ }
+ } else {
+ setErrorMessage('HTTP error: ' + response.status);
+ }
+ } catch (error) {
+ setErrorMessage('An error occurred: ' + error.message + '.');
+ }
+};
+
+ return (
+
+
+
+
+
+ {editing ? ( // Conditional rendering based on editing mode
+ <> {/* Fragment */}
+ }
+ onClick={handleSave}
+ sx={{ mb: 2, width: '150px', height: '40px' }}
+ >
+ Go Back
+
+
+
+
+ {/* Input fields for editing profile information */}
+ Edit Profile Information
+
+ {/* Other input fields */}
+
+
+ >
+ ) : (
+ <> {/* Fragment */}
+ }
+ onClick={() => navigate('/')}
+ sx={{ mb: 2, width: '150px', height: '40px' }}
+ >
+ Go Back
+
+ Profile Information
+ {/* Displaying profile information */}
+ First Name: {profileInfo.first_name}
+ {/* Other profile information */}
+
+ >
+ )}
+
+
+
+ );
+};
+
+export default ProfilePage; // Exporting ProfilePage component
diff --git a/Registration.jsx b/Registration.jsx
new file mode 100644
index 0000000..0fde2d7
--- /dev/null
+++ b/Registration.jsx
@@ -0,0 +1,130 @@
+import React, { useState } from 'react'; // Importing necessary modules from React
+import { useNavigate } from 'react-router-dom'; // Importing useNavigate hook from react-router-dom
+import {
+ Avatar,
+ Button,
+ CssBaseline,
+ TextField,
+ Grid,
+ Box,
+ Typography,
+ Container,
+ Snackbar,
+} from '@mui/material'; // Importing necessary components from Material-UI
+import AccountBoxIcon from '@mui/icons-material/AccountBox'; // Importing AccountBoxIcon from Material-UI
+
+// Functional component Registration
+export default function Registration() {
+ const navigate = useNavigate(); // Getting navigation function using useNavigate hook from react-router-dom
+
+ const [showSnackbar, setShowSnackbar] = useState(false); // State to manage snackbar visibility
+ const [snackbarMessage, setSnackbarMessage] = useState(''); // State to manage snackbar message
+ const [formData, setFormData] = useState({ // State to store form data
+ firstName: '',
+ lastName: '',
+ username: '',
+ email: '',
+ password: '',
+ });
+
+ // Function to handle changes in input fields
+ const handleInputChange = (e) => {
+ const { name, value } = e.target;
+ setFormData((prevFormData) => ({
+ ...prevFormData,
+ [name]: value,
+ }));
+ };
+
+ // Function to handle user registration
+ const handleRegistration = async (e) => {
+ e.preventDefault();
+ try {
+ const response = await fetch('http://127.0.0.1:5000/auth/register', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(formData),
+ });
+
+ if (response.ok) {
+ const data = await response.json();
+ setSnackbarMessage(data.message); // Setting snackbar message with response data
+ setShowSnackbar(true); // Showing the snackbar
+ } else {
+ console.error('HTTP error:', response.status);
+ }
+ } catch (error) {
+ console.error('Error during submission:', error);
+ }
+ };
+
+ return (
+
+
+
+
+
+
+
+ Need an account?
+
+ {/* Registration form */}
+
+
+
+
+
+ {/* Other input fields */}
+
+
+ {/* Button to navigate to login page */}
+
+
+
+ {/* Snackbar for displaying messages */}
+ setShowSnackbar(false)}
+ message={
+
+ {snackbarMessage}
+
+ }
+ anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}
+ />
+
+ );
+}
diff --git a/main.jsx b/main.jsx
new file mode 100644
index 0000000..b486644
--- /dev/null
+++ b/main.jsx
@@ -0,0 +1,36 @@
+import React from 'react'; // Importing React library
+import ReactDOM from 'react-dom/client'; // Importing ReactDOM for rendering
+import App from './App.jsx'; // Importing the main App component
+import '@fontsource/roboto/300.css'; // Importing Roboto font styles
+import '@fontsource/roboto/400.css';
+import '@fontsource/roboto/500.css';
+import '@fontsource/roboto/700.css';
+import { ThemeProvider, createTheme} from '@mui/material/styles'; // Importing ThemeProvider and createTheme from Material-UI
+
+// Creating a custom theme for the application
+const theme = createTheme({
+ components: {
+ MuiButton: { // Customizing the style of MuiButton component
+ styleOverrides: {
+ root: {
+ textTransform: 'none', // Disabling text transformation for MuiButton
+ },
+ },
+ },
+ },
+ palette: {
+ primary: {
+ main: '#0866ff' // Defining the main color for the primary palette
+ },
+ },
+});
+
+// Rendering the application inside the root element
+ReactDOM.createRoot(document.getElementById('root')).render(
+
+ {/* Wrapping the entire application with ThemeProvider to provide the custom theme */}
+
+ {/* Rendering the main App component */}
+
+ ,
+);
diff --git a/products.jsx b/products.jsx
new file mode 100644
index 0000000..22c7d6a
--- /dev/null
+++ b/products.jsx
@@ -0,0 +1,86 @@
+import React, { useEffect, useState } from 'react'; // Importing necessary modules from React
+import { useNavigate } from "react-router-dom"; // Importing useNavigate hook from react-router-dom
+import { Button, CircularProgress, Grid } from '@mui/material'; // Importing necessary components from Material-UI
+import ArrowBackIcon from '@mui/icons-material/ArrowBack'; // Importing ArrowBackIcon from Material-UI
+
+// Functional component ShowProducts
+function ShowProducts() {
+ const [products, setProducts] = useState([]); // State to store products fetched from the backend
+ const [loading, setLoading] = useState(true); // State to manage loading state
+ const navigate = useNavigate(); // Getting navigation function using useNavigate hook from react-router-dom
+
+ // useEffect hook to fetch products when the component mounts
+ useEffect(() => {
+ // Fetching products from the backend
+ fetch('http://localhost:5000/products')
+ .then(response => response.json()) // Parsing response data as JSON
+ .then(data => {
+ setProducts(data); // Updating products state with fetched data
+ setLoading(false); // Setting loading state to false after data is fetched
+ })
+ .catch(error => {
+ console.error("There was an error!", error); // Logging error to the console
+ setLoading(false); // Setting loading state to false in case of error
+ });
+ }, []);
+
+ // Function to group products into pairs for grid layout
+ const groupProductsIntoPairs = (products) => {
+ return products.reduce((resultArray, item, index) => {
+ const chunkIndex = Math.floor(index / 2);
+
+ if (!resultArray[chunkIndex]) {
+ resultArray[chunkIndex] = [];
+ }
+
+ resultArray[chunkIndex].push(item);
+
+ return resultArray;
+ }, []);
+ };
+
+ return (
+
+ {/* Button to navigate back */}
+ } // Icon for back arrow
+ onClick={() => navigate('/')} // Click event to navigate back to home
+ sx={{ mb: 2, width: '150px', height: '40px' }} // Custom styles for button
+ >
+ Go Back
+
+ {/* Header section */}
+
+
Products
+ {/* Displaying loading spinner if data is being fetched */}
+ {loading ? (
+
+ ) : (
+ // Grid layout to display products
+
+ {/* Mapping through grouped product pairs and rendering them */}
+ {groupProductsIntoPairs(products).map((productPair, index) => (
+
+ {/* Mapping through product pair and rendering individual product cards */}
+ {productPair.map(product => (
+
+
{product.model_name}
+
{product.description}
+ {/* Rendering product image if available */}
+ {product.image && (
+
+ )}
+