Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 23 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,9 @@ The current KinTree project team as of Fall 2025 includes Andrea Ambrose, Matthe

### Prerequisites

Node.js (install the correct version for your own OS [here](https://nodejs.org/en)) and get your Supabase URL, CLIENT KEY, and SERVICE KEY from your project dashboard [here](https://supabase.com/)
Node.js (install the correct version for your own OS [here](https://nodejs.org/en)) and install MySQL [here](https://dev.mysql.com/downloads/mysql/). Set up account information through the Configurator application or through the terminal.

### Database Setup

In the /server/ folder, add an .env file with variables `SUPABASE_URL` and `SUPABASE_SERVICE_ROLE_KEY`.
In the /client/ folder, add an .env file with variables `REACT_APP_SUPABASE_URL` and `REACT_APP_SUPABASE_ANON_KEY`.

### Web Application Setup
### Setup

To set up the KinTree codebase on your own machine, start by cloning the repository to your local file system.

Expand All @@ -39,3 +34,24 @@ Then, from the same directory, run the following command to run the server/API:

`node server.js`

### Database Setup

Open the MySQL Client Terminal, login with your password to run the mySQL server.

Create a new database instance on your machine:
`CREATE DATABASE <name>`

In the /server/ directory, create a .env file with MySQL information. Example env is in the project's /docs/ folder.

Open another command line window in /SeniorProject_KinTree/server/ and run the command `npm install knex mysql2` to install Knex and mySQL2.

Verify the connection:

`node mysql-connection.js`

Ensure proper migration files are loaded:

`npx knex:migrate status`

Run the command `npx knex migrate:latest` to create and/or update existing database tables.

130 changes: 3 additions & 127 deletions client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
"private": true,
"dependencies": {
"@hookform/resolvers": "^4.1.3",
"@supabase/supabase-js": "^2.75.0",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
Expand Down
90 changes: 19 additions & 71 deletions client/src/CurrentUserProvider.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { React, useState, createContext, useContext, useEffect } from "react"
import { supabase } from "./utils/supabaseClient";
import { set } from "react-hook-form";

export const currentContext = createContext();

export const CurrentUserProvider = ({ children }) => {
const [currentUserID, setCurrentUserIDState] = useState('');
const [currentAccountID, setCurrentAccountIDState] = useState('');
const [currentAccountID, setCurrentAccountIDState] = useState(''); // TODO login will set this
const [currentUserName, setCurrentUserNameState] = useState('');
const [loading, setLoading] = useState(true);
const [supabaseUser, setSupabaseUser] = useState(null);

const setCurrentAccountID = (accountID) => { // logging in will trigger this
localStorage.setItem("currentAccountID", accountID);
Expand Down Expand Up @@ -53,80 +52,29 @@ export const CurrentUserProvider = ({ children }) => {
}


// Initialize Supabase auth state
// init
useEffect(() => {
const initializeAuth = async () => {
try {
// Get initial session
const { data: { session } } = await supabase.auth.getSession();

if (session?.user) {
setSupabaseUser(session.user);
setCurrentAccountIDState(session.user.id);
setCurrentUserNameState(session.user.email); // Use email as default username
}

setLoading(false);
} catch (error) {
console.error('Error initializing auth:', error);
setLoading(false);
}
};
const initializeState = () => {
const storedAccountID = localStorage.getItem("currentAccountID");
const storedUserID = localStorage.getItem("currentUserID");
const storedUserName = localStorage.getItem("currentUserName");

initializeAuth();

// Listen for auth changes
const { data: { subscription } } = supabase.auth.onAuthStateChange(
async (event, session) => {
if (session?.user) {
setSupabaseUser(session.user);
setCurrentAccountIDState(session.user.id);
setCurrentUserNameState(session.user.email);
// Auto-sync profile into public.users using auth metadata when available
try {
const m = session.user.user_metadata || {};
await fetch('http://localhost:5000/api/auth/sync', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
auth_uid: session.user.id,
email: session.user.email,
username: session.user.email,
firstName: m.firstName || m.first_name || null,
lastName: m.lastName || m.last_name || null,
phoneNumber: m.phoneNumber || m.phone_number || m.phonenum || null,
birthDate: m.birthDate || m.birthdate || null,
})
});
} catch (e) {
console.warn('Auth sync failed:', e?.message || e);
}
} else {
setSupabaseUser(null);
setCurrentAccountIDState('');
setCurrentUserNameState('');
}
setLoading(false);
if (storedAccountID) {
setCurrentAccountIDState(storedAccountID);
}
);

return () => subscription.unsubscribe();
if (storedUserID) {
setCurrentUserIDState(storedUserID);
}
if (storedUserName) {
setCurrentUserNameState(storedUserName);
}
setLoading(false);
};
initializeState();
}, []);

return (
<currentContext.Provider value={{
loading,
currentAccountID,
setCurrentAccountIDState,
currentUserID,
setCurrentUserIDState,
setCurrentAccountID,
setCurrentUserID,
fetchCurrentUserID,
fetchCurrentAccountID,
currentUserName,
supabaseUser
}}>
<currentContext.Provider value={{ loading, currentAccountID, setCurrentAccountIDState, currentUserID, setCurrentUserIDState, setCurrentAccountID, setCurrentUserID, fetchCurrentUserID, fetchCurrentAccountID, currentUserName }}>
{children}
</currentContext.Provider>
)
Expand Down
Loading