Skip to content

kacyphan7/RxReMinder-FrontEnd

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

About

RxReMinder is a web application that helps users manage their medications. The application provides a variety of features, including:

  • A prescription management system that allows users to track their prescriptions and set recurring reminders for medication doses.
  • A user-driven medication database that provides classification and directions specific to medications.
  • A dose tracking system that allows users to track upcoming, taken, and missed doses.
  • A notification system that reminds users via email when it's time to take their medications.

RxReMinder is under development, but has the potential to be a valuable tool for anyone who takes medications. The application is easy to use and provides a variety of features that can help users stay on top of their medication.

Built With

CSS3 Express.js Heroku MongoDB Netlify Next.js NODE.JS Postman React

Deployment


Getting Started

Prerequisites

Backend

  1. fork and clone the RxReMinder-BE repository.
git clone https://github.com/your-username/RxReMinder-BE.git
cd RxReMinder-BE
  1. Install dependencies.
npm install
  1. Create a .env file in the repository root and add the follow environment variables:
MONGO_URI=insert-your-database-uri-here
JWT_SECRET=secret-key-of-your-choice
COURIER_KEY=your-courier-api-key-here
  1. Start the backend server.
npm run dev

Database seeding (optional)

  • Use the following command to pre-load your database with a provided collection of common medications.
node seeders/medications.js

Frontend

  1. fork and clone the RxReMinder-FrontEnd repository.
git clone https://github.com/your-username/RxReMinder-FrontEnd
cd RxReMinder-FrontEnd
  1. Install dependencies.
npm install
  1. Create a .env file in the repository root and add the following environment variable:
NEXT_PUBLIC_SERVER_URL=http://localhost:8000
  1. Start the frontend server.
npm run dev
  1. Open http://localhost:3000 with your web browser to experience the app.

Notification Engine

  • Set up a recurring engine to run node notifications.js on the backend server.
  • The deployed version of RxReMinder uses Heroku Scheduler for this purpose.
  • Alternatives include Netlify Functions or simply cron where allowed.

Screenshots

Home

Home Component1 Component2

Login

Login

Register

Register

Dashboard

Dashboard

Profile

Profile

Add Prescription

Prescription

Manage Prescription

Manage Prescription

View Single Prescription

View Single Prescription

Medication

Medication

Email Reminder

Email


Frontend Code Snippets

  • See the README in the Backend Repo for backend code snippets.

Interdependent Dashboard Modules

// In Dashboard
const [refreshPercentage, setRefreshPercentage] = useState(false);
...
<DailyPercentage shouldRefresh={refreshPercentage} />
<DayDoses onDoseTaken={setRefreshPercentage} />
...
// In DailyPercentage component
const DailyPercentage = ({ shouldRefresh }) => {
    useEffect(() => {
        axios.get(`${process.env.NEXT_PUBLIC_SERVER_URL}/doses/dailypercentage`)
            .then(response => {
                if (response.data !== null) {
                    setPercentage(response.data);
                }
                setLoading(false);
            })
            .catch(error => {
                console.error("There was an error fetching the percentage data: ", error);
                setLoading(false);
            });
    }, [user, shouldRefresh]);

    useEffect(() => {
        if (!loading) {
            let ctx = document.getElementById('doughnut-chart').getContext('2d');
            if (chartRef.current) {
                chartRef.current.destroy();
            }
            ...
            chartRef.current = new Chart(ctx, {
                ...
            });
        }
    }, [loading, percentage]);
}

Weekly Progress Bar Chart

 const daysOfWeek = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
    const sunWeek = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"];
    const monWeek = ["Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday", "Monday"];
    const tuesWeek = ["Wednesday", "Thursday", "Friday", "Saturday", "Sunday", "Monday", "Tuesday"];
    const wedWeek = ["Thursday", "Friday", "Saturday", "Sunday", "Monday", "Tuesday", "Wednesday"];
    const thurWeek = ["Friday", "Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday"];
    const friWeek = ["Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday"];
    const satWeek = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];

    const today = new Date().getDay();
    let weekLabel;

    switch (daysOfWeek[today]) {
        case "Sunday": weekLabel = sunWeek; break;
        case "Monday": weekLabel = monWeek; break;
        case "Tuesday": weekLabel = tuesWeek; break;
        case "Wednesday": weekLabel = wedWeek; break;
        case "Thursday": weekLabel = thurWeek; break;
        case "Friday": weekLabel = friWeek; break;
        case "Saturday": weekLabel = satWeek; break;
    }

    ...

    useEffect(() => {
        if (percentage) {
            let ctx = document.getElementById('myChart').getContext('2d');
            if (chartRef.current) {
                chartRef.current.destroy();
            }
            percentage.forEach((item) => {
                item = item + '%'
            });
            Chart.register(gradient)
            Chart.defaults.scale.grid.lineWidth = 0
            chartRef.current = new Chart(ctx, {
                type: 'bar',
                data: {
                    labels: weekLabel,
                ...
                }
            });
        }
    }, [percentage, weekLabel]);

Multi-Step New Prescription Form

const [formData, setFormDate] = useState({
    medId: '',
    quantity: '',
    freq: '',
    time1: '',
    time2: '',
    startDate: '',
    endDate: '',
    notes: '',
    timezone: (new Date().getTimezoneOffset()) / 60,
});

function setFormData(newFormData) {
    setFormDate({ ...formData, ...newFormData });
}

const conditionalComponent = () => {
    switch (page) {
        case 0:
            return <OneMedication formData={formData} setFormData={setFormData} />;
        case 1:
            return <TwoFrequency formData={formData} setFormData={setFormData} />;
        case 2:
            return <ThreeTime formData={formData} setFormData={setFormData} />;
        case 3:
            return <FourDuration formData={formData} setFormData={setFormData} />;
        case 4:
            return <FiveDirections formData={formData} setFormData={setFormData} />;
        default:
            return <OneMedication formData={formData} setFormData={setFormData} />;
    }
};
...
<h1>Add Prescription</h1>
<div className={styles.formSection}>
    {error ? <p>There was an error submitting your form. Please try again.</p> : null}
    {conditionalComponent()}
    {page > 0 && <button className="button" onClick={() => setPage(page - 1)}>Back</button>}
    <button className="button" onClick={handleSubmit}>{page < 4 ? "Next" : "Submit"}</button>
</div>
...
// In OneMedication component
export default function OneMedication({formData, setFormData}) {

    function handleQuantity(e) {
        setFormData({ ...formData, quantity: e.target.value });
    }

    return (
        <>
            <div className="field">
                <label htmlFor="name">What medication are you taking?</label>
                <MedicationSearch formData={formData} setFormData={setFormData} />
            </div>
            <div className="field">
                <label htmlFor="dosage">What is the amount per dose?</label>
                <input className="input" type="text" name="quantity" placeholder="Quantity" onChange={handleQuantity} value={formData['quantity']} />
            </div>
        </>
    );
}
...
// In TwoFrequency component
export default function TwoFrequency({formData, setFormData}) {
    function handleFreq(e) {
        setFormData({ ...formData, freq: e.target.value });
    }

    useEffect(() => {
        // effectively makes the default value 'once a day'
        if (formData['freq'] === '') {
            setFormData({ ...formData, freq: 'once' });
        }
    }, []);
    
    return (
        <div className="field">
            <label htmlFor="name">How often would you like to take this medication?</label>
            <select className="input" name="freq" onChange={handleFreq} value={formData['freq']}>
                <option value="once">Once a Day</option>
                <option value="twice">Twice a Day</option>
                <option value="alternate">Every Other Day</option>
                <option value="weekly">Once a Week</option>
            </select>
        </div>
    );
}


Wireframe and Entity Relationship Diagram

Future Enhancements

  • QR Code for each prescription
  • Health Insurance Information
  • Medications Generic and Brand Name
  • Medication Side Effects
  • Medication Interactions
  • Health Care Provider

Stretch Goals

If permitted by legal we would like to essentially partnered with pharmacists to get the prescription information to automatically be entered into our database with user permission. This will allow the user to have a more seamless experience with their refill automatically being added to their profile.

Resources

  • Chart JS - A JavaScript library for creating beautiful charts.
  • Courier - A notification platform that helps developers add notifications to their applications.
  • Faker - A library for generating fake data.
  • Font Awesome - An iconic font and CSS toolkit.
  • uiZard - A platform that uses AI to transform your hand-drawn wireframes into code.

License

The source code for the site is licensed under the MIT license, which you can find in the MIT-LICENSE.txt file.

Authors