Conversation
…ctioning sorting for Patient Name, Assigned Social Worker, and Last Contact.
Auth Pages Design
Implemented _index.tsx (home page) using temporary JSON data with fun…
firebase setup
Tb/frontend auth
…t, and add functionality. Updated styling.Added website button.
There was a problem hiding this comment.
Pull request overview
Adds Firebase-backed authentication and a new referrals UI flow (list/cards + add/edit/delete dialog), wiring them into the React Router app structure and updating project config/dependencies to support local Firebase development.
Changes:
- Added Firebase Auth context/provider plus auth flows (login, create account, verify email, forgot password) and route guards.
- Implemented referrals UI (page, list, cards, form dialog) and Firestore hook for CRUD operations.
- Updated build/runtime config (SPA mode, Vite polling watch), dependencies, lint ignores, and environment templates.
Reviewed changes
Copilot reviewed 28 out of 32 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| vite.config.ts | Enables polling file watcher for dev server stability. |
| tsconfig.json | Suppresses TypeScript deprecation warnings. |
| react-router.config.ts | Switches app to SPA mode by disabling SSR. |
| package.json | Adds Firebase + lucide-react and router deps/types. |
| package-lock.json | Locks new dependencies and transitive packages. |
| eslint.config.ts | Ignores generated build/** output in ESLint. |
| app/types/user.ts | Adds typed user model for Firestore/user data. |
| app/types/referral.ts | Adds typed referral + joined referral-with-provider model. |
| app/services/firebase_provider.tsx | Introduces AuthProvider and useAuth() context hook. |
| app/services/firebase_app.ts | Initializes Firebase app and exports Auth instance. |
| app/services/auth_service.ts | Wraps sign-up/login flows with persistence + verification. |
| app/routes/verify_email.tsx | Adds verify-email UI and resend/continue actions. |
| app/routes/starter.tsx | Removes starter template landing page route. |
| app/routes/require_guest.tsx | Adds guest-only route guard (redirects logged-in users). |
| app/routes/require_auth.tsx | Adds auth-required route guard (redirects unauth/ unverified). |
| app/routes/referrals.tsx | Adds standalone referrals page wiring list + dialog + hook. |
| app/routes/login.tsx | Adds login UI wired to Firebase Auth. |
| app/routes/forgot_pass.tsx | Adds forgot-password UI using Firebase reset email flow. |
| app/routes/create_account.tsx | Adds create-account UI + terms gating + verification flow. |
| app/routes/change_password.tsx | Adds (currently unused) change password page placeholder. |
| app/routes/_index.tsx | Replaces home page with a dashboard UI using auth context. |
| app/routes.ts | Replaces route config with guarded auth/guest routing layout. |
| app/root.tsx | Wraps app layout in AuthProvider. |
| app/hooks/useReferrals.ts | Adds Firestore-backed referrals query + CRUD helpers. |
| app/firebase.js | Adds Firestore db initialization module. |
| app/components/ReferralsList.tsx | Adds referrals list UI and “Add” action. |
| app/components/ReferralFormDialog.tsx | Adds add/edit referral modal form UI. |
| app/components/ReferralCard.tsx | Adds referral card UI with edit/delete actions. |
| app/app.css | Improves default text colors for light/dark mode. |
| .gitignore | Ignores .env (and keeps build/react-router ignores). |
| .env.template | Adds Firebase env var template for local setup. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| export default [ | ||
| //protected routes | ||
| route("", "routes/require_auth.tsx", [index("routes/_index.tsx")]), | ||
|
|
||
| //routes require user to not be logged in | ||
| route("", "routes/require_guest.tsx", [ | ||
| route("login", "routes/login.tsx"), | ||
| route("create-account", "routes/create_account.tsx"), | ||
| ]), | ||
|
|
||
| //routes available to anyone | ||
| route("forgot-pass", "routes/forgot_pass.tsx"), | ||
| route("verify-email", "routes/verify_email.tsx"), | ||
| ] satisfies RouteConfig; |
There was a problem hiding this comment.
The PR description says the referrals UI is currently displayed on referrals.tsx, but there is no route configured for it here, so it won't be reachable in the app. Add a route for routes/referrals.tsx (likely under require_auth) or update the PR description to match the actual navigation.
| <a | ||
| href="#" | ||
| className="font-medium text-gray-900 underline underline-offset-2" | ||
| > | ||
| Logout | ||
| </a> |
There was a problem hiding this comment.
The "Logout" UI is a dead link (href="#") and doesn't call the auth logout() function, so users can't actually sign out (and clicking it will also jump to the top of the page). Replace this with a button that calls logout() from useAuth() and then navigates to /login (or relies on RequireGuest/RequireAuth redirects).
| <a | |
| href="#" | |
| className="font-medium text-gray-900 underline underline-offset-2" | |
| > | |
| Logout | |
| </a> | |
| <button | |
| type="button" | |
| onClick={async () => { | |
| await logout(); | |
| navigate("/login"); | |
| }} | |
| className="font-medium text-gray-900 underline underline-offset-2" | |
| > | |
| Logout | |
| </button> |
| {/* Header Title */} | ||
| <div className="mb-3 flex items-center justify-between"> | ||
| <h2 className="text-[20px] font-semibold text-black"> | ||
| David Thompsons Referrals |
There was a problem hiding this comment.
Grammatical typo in the header: "David Thompsons Referrals" is missing the apostrophe. Consider "David Thompson's Referrals" (or make this dynamic once patient data is available).
| David Thompsons Referrals | |
| David Thompson's Referrals |
| "@types/node": "^20", | ||
| "@types/react": "^19.1.2", | ||
| "@types/react-dom": "^19.1.2", | ||
| "@types/react-router-dom": "^5.3.3", |
There was a problem hiding this comment.
@types/react-router-dom is pinned to v5.3.3, but this repo is using React Router v7 (react-router/react-router-dom 7.x). The v5 DefinitelyTyped package is incompatible and can cause incorrect types or conflicts. Remove @types/react-router-dom (and @types/react-router) and rely on the built-in types shipped with React Router v7, or align to the correct major versions consistently.
| "@types/react-router-dom": "^5.3.3", |
| // Perform the "join" by fetching associated users | ||
| const populatedReferrals = await Promise.all( | ||
| baseReferrals.map(async (ref) => { | ||
| let socialWorker: User | undefined; | ||
|
|
||
| // Fetch referring Social Worker | ||
| if (ref.socialWorkerId) { | ||
| const swDoc = await getDoc( | ||
| doc(db, "users", ref.socialWorkerId) | ||
| ); | ||
| if (swDoc.exists()) { | ||
| socialWorker = { | ||
| uid: swDoc.id, | ||
| ...swDoc.data(), | ||
| } as User; | ||
| } | ||
| } | ||
|
|
||
| return { | ||
| ...ref, | ||
| socialWorker, | ||
| }; | ||
| }) | ||
| ); |
There was a problem hiding this comment.
useReferrals performs a per-referral getDoc() for the social worker on every snapshot update. This creates an N+1 pattern and can become slow/expensive as referrals grow. Consider caching users by id, denormalizing the needed social worker fields onto the referral document, or batching lookups (e.g., where(documentId(), 'in', ...) in chunks) instead of fetching each doc individually.
| referralPhone?: string; | ||
|
|
||
| type: string; | ||
| status: string; |
There was a problem hiding this comment.
ReferralFormData.status is typed as string, but Referral.status is a constrained union (pending/accepted/completed/rejected). As-is, invalid status values can be submitted and stored without TypeScript catching it. Type this field as Referral["status"] (or the explicit union) to keep form inputs and persisted data consistent.
| status: string; | |
| status: Referral["status"]; |
| addDoc, | ||
| Timestamp, | ||
| } from "firebase/firestore"; | ||
| import { db } from "~/firebase"; |
There was a problem hiding this comment.
useReferrals imports db from "~/firebase", but the file added is app/firebase.js. With the current tsconfig.json (no allowJs), TypeScript builds/typecheck will fail to resolve/compile JS modules. Rename the Firebase module to app/firebase.ts (or app/firebase_app.ts) and export db from there, or enable allowJs (less preferred).
| import { db } from "~/firebase"; | |
| import { db } from "../firebase"; |
| import { initializeApp } from "firebase/app"; | ||
| import { getFirestore } from "firebase/firestore"; | ||
|
|
||
| const firebaseConfig = { | ||
| apiKey: import.meta.env.VITE_FIREBASE_API_KEY, | ||
| authDomain: import.meta.env.VITE_FIREBASE_AUTH_DOMAIN, | ||
| projectId: import.meta.env.VITE_FIREBASE_PROJECT_ID, | ||
| storageBucket: import.meta.env.VITE_FIREBASE_STORAGE_BUCKET, | ||
| messagingSenderId: import.meta.env.VITE_FIREBASE_MESSAGING_SENDER_ID, | ||
| appId: import.meta.env.VITE_FIREBASE_APP_ID, | ||
| measurementId: import.meta.env.VITE_FIREBASE_MEASUREMENT_ID, | ||
| }; | ||
|
|
||
| const app = initializeApp(firebaseConfig); | ||
| export const db = getFirestore(app); |
There was a problem hiding this comment.
This file calls initializeApp(firebaseConfig) even though app/services/firebase_app.ts also initializes the default Firebase app. Importing both modules in the same bundle will throw "Firebase App named '[DEFAULT]' already exists" at runtime. Consolidate initialization into a single module and have both auth and firestore use the same app instance (e.g., getApps().length ? getApp() : initializeApp(...)).
| // Your web app's Firebase configuration | ||
| // For Firebase JS SDK v7.20.0 and later, measurementId is optional | ||
| const firebaseConfig = { | ||
| apiKey: import.meta.env.VITE_FIREBASE_API_KEY, | ||
| authDomain: import.meta.env.VITE_FIREBASE_AUTH_DOMAIN, | ||
| projectId: import.meta.env.VITE_FIREBASE_PROJECT_ID, | ||
| storageBucket: import.meta.env.VITE_FIREBASE_STORAGE_BUCKET, | ||
| messagingSenderId: import.meta.env.VITE_FIREBASE_MESSAGING_SENDER_ID, | ||
| appId: import.meta.env.VITE_FIREBASE_APP_ID, | ||
| measurementId: import.meta.env.VITE_FIREBASE_MEASUREMENT_ID, | ||
| }; | ||
|
|
||
| // Initialize Firebase | ||
| const app = initializeApp(firebaseConfig); | ||
| //const analytics = getAnalytics(app); | ||
| const auth = getAuth(app); | ||
|
|
||
| export { app, auth }; |
There was a problem hiding this comment.
This module initializes the default Firebase app. Since app/firebase.js also initializes the default app, importing auth + firestore together will cause a duplicate-app runtime error. Prefer a single shared initializer that exports app, auth, and db, using getApps()/getApp() guards if needed.
Implemented Referrals Card, List, and Form Dialog that works with our Firebase Database. Currently, it is being displayed on referrals.tsx since we eventually want it on the same page as messages so for now it will remain separate until we can merge. The Edit, Add, and Delete functions work for the referrals. For now, we are using a static variable to keep track of the current user which will be changed later on using route params.