From 668d0075912dfd49ea26247f499f71a338eb868c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Salazar?=
<73718835+joshrs23@users.noreply.github.com>
Date: Fri, 28 Nov 2025 10:34:29 -0500
Subject: [PATCH 01/15] user entitie
---
dataconnect/connector/user/mutations.gql | 41 ++++++++++++++++++++++
dataconnect/connector/user/queries.gql | 43 ++++++++++++++++++++++++
dataconnect/schema/user.gql | 15 +++++++++
3 files changed, 99 insertions(+)
create mode 100644 dataconnect/connector/user/mutations.gql
create mode 100644 dataconnect/connector/user/queries.gql
create mode 100644 dataconnect/schema/user.gql
diff --git a/dataconnect/connector/user/mutations.gql b/dataconnect/connector/user/mutations.gql
new file mode 100644
index 00000000..cf6444fe
--- /dev/null
+++ b/dataconnect/connector/user/mutations.gql
@@ -0,0 +1,41 @@
+mutation CreateUser(
+ $id: UUID!, # Firebase UID
+ $email: String!,
+ $fullName: String!,
+ $role: UserBaseRole!,
+ $userRole: String
+) @auth(level: USER) {
+ user_insert(
+ data: {
+ id: $id
+ email: $email
+ fullName: $fullName
+ role: $role
+ userRole: $userRole
+ }
+ )
+}
+
+mutation UpdateUser(
+ $id: String!,
+ $email: String,
+ $fullName: String,
+ $role: UserBaseRole,
+ $userRole: String
+) @auth(level: USER) {
+ user_update(
+ id: $id,
+ data: {
+ email: $email
+ fullName: $fullName
+ role: $role
+ userRole: $userRole
+ }
+ )
+}
+
+mutation DeleteUser(
+ $id: String!
+) @auth(level: USER) {
+ user_delete(id: $id)
+}
diff --git a/dataconnect/connector/user/queries.gql b/dataconnect/connector/user/queries.gql
new file mode 100644
index 00000000..417860bf
--- /dev/null
+++ b/dataconnect/connector/user/queries.gql
@@ -0,0 +1,43 @@
+query listUsers @auth(level: USER) {
+ users {
+ id
+ email
+ fullName
+ role
+ userRole
+ createdDate
+ updatedDate
+ }
+}
+
+query getUserById(
+ $id: String!
+) @auth(level: USER) {
+ user(id: $id) {
+ id
+ email
+ fullName
+ role
+ userRole
+ }
+}
+
+query filterUsers(
+ $email: String,
+ $role: UserBaseRole,
+ $userRole: String
+) @auth(level: USER) {
+ users(
+ where: {
+ email: { eq: $email }
+ role: { eq: $role }
+ userRole: { eq: $userRole }
+ }
+ ) {
+ id
+ email
+ fullName
+ role
+ userRole
+ }
+}
diff --git a/dataconnect/schema/user.gql b/dataconnect/schema/user.gql
new file mode 100644
index 00000000..b5982534
--- /dev/null
+++ b/dataconnect/schema/user.gql
@@ -0,0 +1,15 @@
+enum UserBaseRole {
+ ADMIN
+ USER
+}
+
+type User @table(name: "users") {
+ id: UUID! # user_id / uid de Firebase
+ email: String!
+ fullName: String!
+ role: UserBaseRole!
+ userRole: String
+ createdDate: Timestamp @default(expr: "request.time")
+ updatedDate: Timestamp @default(expr: "request.time")
+ createdBy: String @default(expr: "auth.uid")
+}
From ab6816c7abc0a531b00eb3e8a5a68b9ba5286ac6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Salazar?=
<73718835+joshrs23@users.noreply.github.com>
Date: Fri, 28 Nov 2025 10:42:02 -0500
Subject: [PATCH 02/15] adding/editing 2 entities
---
internal-api-harness/src/api/krowSDK.js | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/internal-api-harness/src/api/krowSDK.js b/internal-api-harness/src/api/krowSDK.js
index 4cfca950..9bada66c 100644
--- a/internal-api-harness/src/api/krowSDK.js
+++ b/internal-api-harness/src/api/krowSDK.js
@@ -139,19 +139,30 @@ entityNames.forEach(entityName => {
});*/
const dataconnectEntityConfig = {
+ User: {
+ list: 'listUsers',
+ get: 'getUserById',
+ create: 'createUser',
+ update: 'updateUser',
+ delete: 'deleteUser',
+ filter: 'filterUsers',
+ },
Event: {
list: 'listEvents',
create: 'createEvent',
- // get: 'getEvent',
- // update: 'updateEvent',
- // delete: 'deleteEvent',
- // filter: 'filterEvents',
+ get: 'getEventById',
+ update: 'updateEvent',
+ delete: 'deleteEvent',
+ filter: 'filterEvents',
},
Staff: {
list: 'listStaff',
create: 'createStaff',
-
+ get: 'getStaffById',
+ update: 'updateStaff',
+ delete: 'deleteStaff',
+ filter: 'filterStaff',
},
Vendor: {
From 4dc1553174883b45463612b4adc971dbc47f1e78 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Salazar?=
<73718835+joshrs23@users.noreply.github.com>
Date: Fri, 28 Nov 2025 10:46:31 -0500
Subject: [PATCH 03/15] modified user id type
---
dataconnect/connector/user/mutations.gql | 4 ++--
dataconnect/connector/user/queries.gql | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/dataconnect/connector/user/mutations.gql b/dataconnect/connector/user/mutations.gql
index cf6444fe..f0da8002 100644
--- a/dataconnect/connector/user/mutations.gql
+++ b/dataconnect/connector/user/mutations.gql
@@ -17,7 +17,7 @@ mutation CreateUser(
}
mutation UpdateUser(
- $id: String!,
+ $id: UUID!,
$email: String,
$fullName: String,
$role: UserBaseRole,
@@ -35,7 +35,7 @@ mutation UpdateUser(
}
mutation DeleteUser(
- $id: String!
+ $id: UUID!
) @auth(level: USER) {
user_delete(id: $id)
}
diff --git a/dataconnect/connector/user/queries.gql b/dataconnect/connector/user/queries.gql
index 417860bf..6675c691 100644
--- a/dataconnect/connector/user/queries.gql
+++ b/dataconnect/connector/user/queries.gql
@@ -11,7 +11,7 @@ query listUsers @auth(level: USER) {
}
query getUserById(
- $id: String!
+ $id: UUID!
) @auth(level: USER) {
user(id: $id) {
id
From 4cbb3c429a478098186cfe90819adb8ac27bd122 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Salazar?=
<73718835+joshrs23@users.noreply.github.com>
Date: Fri, 28 Nov 2025 11:33:03 -0500
Subject: [PATCH 04/15] new firebase file for frontend-web
---
frontend-web/src/firebase.js | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
create mode 100644 frontend-web/src/firebase.js
diff --git a/frontend-web/src/firebase.js b/frontend-web/src/firebase.js
new file mode 100644
index 00000000..9f5e6fb4
--- /dev/null
+++ b/frontend-web/src/firebase.js
@@ -0,0 +1,20 @@
+// Import the functions you need from the SDKs you need
+import { initializeApp } from "firebase/app";
+import { getAuth } from "firebase/auth";
+import { getDataConnect } from 'firebase/data-connect';
+import { connectorConfig } from '@dataconnect/generated';
+
+// Your web app's Firebase configuration
+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
+};
+
+// Initialize Firebase
+const app = initializeApp(firebaseConfig);
+export const dataConnect = getDataConnect(app, connectorConfig);
+export const auth = getAuth(app);
\ No newline at end of file
From 7a1da8c0d477b9f6cd736675334126484b10b7a3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Salazar?=
<73718835+joshrs23@users.noreply.github.com>
Date: Fri, 28 Nov 2025 13:59:29 -0500
Subject: [PATCH 05/15] auth working in webpage
---
.../src/components/auth/ProtectedRoute.jsx | 25 +
.../src/components/auth/PublicRoute.jsx | 25 +
frontend-web/src/hooks/useAuth.js | 19 +
frontend-web/src/pages/Login.jsx | 86 +++
frontend-web/src/pages/Register.jsx | 128 ++++
frontend-web/src/pages/index.jsx | 706 ++++++------------
6 files changed, 531 insertions(+), 458 deletions(-)
create mode 100644 frontend-web/src/components/auth/ProtectedRoute.jsx
create mode 100644 frontend-web/src/components/auth/PublicRoute.jsx
create mode 100644 frontend-web/src/hooks/useAuth.js
create mode 100644 frontend-web/src/pages/Login.jsx
create mode 100644 frontend-web/src/pages/Register.jsx
diff --git a/frontend-web/src/components/auth/ProtectedRoute.jsx b/frontend-web/src/components/auth/ProtectedRoute.jsx
new file mode 100644
index 00000000..22384a45
--- /dev/null
+++ b/frontend-web/src/components/auth/ProtectedRoute.jsx
@@ -0,0 +1,25 @@
+import React from 'react';
+import { Navigate } from 'react-router-dom';
+import { useAuth } from '@/hooks/useAuth';
+import { Loader2 } from 'lucide-react';
+
+export default function ProtectedRoute({ children }) {
+ const { user, loading } = useAuth();
+
+ if (loading) {
+ return (
+
+ );
+ }
+
+ if (!user) {
+ return ;
+ }
+
+ return children;
+}
\ No newline at end of file
diff --git a/frontend-web/src/components/auth/PublicRoute.jsx b/frontend-web/src/components/auth/PublicRoute.jsx
new file mode 100644
index 00000000..55d4d0d8
--- /dev/null
+++ b/frontend-web/src/components/auth/PublicRoute.jsx
@@ -0,0 +1,25 @@
+import React from 'react';
+import { Navigate } from 'react-router-dom';
+import { useAuth } from '@/hooks/useAuth';
+import { Loader2 } from 'lucide-react';
+
+export default function PublicRoute({ children }) {
+ const { user, loading } = useAuth();
+
+ if (loading) {
+ return (
+
+ );
+ }
+
+ if (user) {
+ return ;
+ }
+
+ return children;
+}
\ No newline at end of file
diff --git a/frontend-web/src/hooks/useAuth.js b/frontend-web/src/hooks/useAuth.js
new file mode 100644
index 00000000..51d3b33e
--- /dev/null
+++ b/frontend-web/src/hooks/useAuth.js
@@ -0,0 +1,19 @@
+import { useState, useEffect } from 'react';
+import { onAuthStateChanged } from 'firebase/auth';
+import { auth } from '@/firebase';
+
+export function useAuth() {
+ const [user, setUser] = useState(null);
+ const [loading, setLoading] = useState(true);
+
+ useEffect(() => {
+ const unsubscribe = onAuthStateChanged(auth, (user) => {
+ setUser(user);
+ setLoading(false);
+ });
+
+ return () => unsubscribe();
+ }, []);
+
+ return { user, loading };
+}
\ No newline at end of file
diff --git a/frontend-web/src/pages/Login.jsx b/frontend-web/src/pages/Login.jsx
new file mode 100644
index 00000000..c5263c9f
--- /dev/null
+++ b/frontend-web/src/pages/Login.jsx
@@ -0,0 +1,86 @@
+import React, { useState } from "react";
+import { useNavigate, Link } from "react-router-dom";
+import { signInWithEmailAndPassword } from "firebase/auth";
+import { auth } from "@/firebase";
+import { Button } from "@/components/ui/button";
+import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
+import { Input } from "@/components/ui/input";
+import { Label } from "@/components/ui/label";
+import { Loader2 } from "lucide-react";
+
+export default function Login() {
+ const navigate = useNavigate();
+ const [email, setEmail] = useState("");
+ const [password, setPassword] = useState("");
+ const [error, setError] = useState(null);
+ const [loading, setLoading] = useState(false);
+
+ const handleLogin = async (e) => {
+ e.preventDefault();
+ setError(null);
+
+ if (!email || !password) {
+ setError("Email and password are required.");
+ return;
+ }
+
+ setLoading(true);
+ try {
+ await signInWithEmailAndPassword(auth, email, password);
+ navigate("/");
+ } catch (error) {
+ setError("Invalid credentials. Please try again.");
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ return (
+
+
+
+ Login
+ Enter your credentials to access your account.
+
+
+
+
+
+
+
+ Don't have an account?{" "}
+
+ Register
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/frontend-web/src/pages/Register.jsx b/frontend-web/src/pages/Register.jsx
new file mode 100644
index 00000000..7e1931e5
--- /dev/null
+++ b/frontend-web/src/pages/Register.jsx
@@ -0,0 +1,128 @@
+import React, { useState } from "react";
+import { useNavigate, Link } from "react-router-dom";
+import { createUserWithEmailAndPassword } from "firebase/auth";
+import { auth } from "@/firebase";
+import { Button } from "@/components/ui/button";
+import {
+ Card,
+ CardContent,
+ CardDescription,
+ CardFooter,
+ CardHeader,
+ CardTitle,
+} from "@/components/ui/card";
+import { Input } from "@/components/ui/input";
+import { Label } from "@/components/ui/label";
+import { Loader2 } from "lucide-react";
+
+export default function Register() {
+ const navigate = useNavigate();
+ const [email, setEmail] = useState("");
+ const [password, setPassword] = useState("");
+ const [error, setError] = useState(null);
+ const [loading, setLoading] = useState(false);
+
+ const validatePassword = (password) => {
+ if (password.length < 6) {
+ return "Password must be at least 6 characters long.";
+ }
+ return null;
+ };
+
+ const validateEmail = (email) => {
+ const re =
+ /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
+ if (!re.test(String(email).toLowerCase())) {
+ return "Invalid email address.";
+ }
+ return null;
+ };
+
+ const handleRegister = async (e) => {
+ e.preventDefault();
+ setError(null);
+
+ if (!email || !password) {
+ setError("Email and password are required.");
+ return;
+ }
+
+ const emailError = validateEmail(email);
+ if (emailError) {
+ setError(emailError);
+ return;
+ }
+
+ const passwordError = validatePassword(password);
+ if (passwordError) {
+ setError(passwordError);
+ return;
+ }
+
+ setLoading(true);
+ try {
+ await createUserWithEmailAndPassword(auth, email, password);
+ navigate("/");
+ } catch (error) {
+ setError(error.message || "Something went wrong. Please try again.");
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ return (
+
+
+
+ Register
+ Create a new account.
+
+
+
+
+
+
+
+
+
+
+ Already have an account?{" "}
+
+ Login
+
+
+
+
+
+ );
+}
diff --git a/frontend-web/src/pages/index.jsx b/frontend-web/src/pages/index.jsx
index c3d5213d..6caeef9f 100644
--- a/frontend-web/src/pages/index.jsx
+++ b/frontend-web/src/pages/index.jsx
@@ -1,477 +1,267 @@
-import Layout from "./Layout.jsx";
-
-import Dashboard from "./Dashboard";
-
-import StaffDirectory from "./StaffDirectory";
-
-import AddStaff from "./AddStaff";
-
-import EditStaff from "./EditStaff";
-
-import Events from "./Events";
-
-import CreateEvent from "./CreateEvent";
-
-import EditEvent from "./EditEvent";
-
-import EventDetail from "./EventDetail";
-
-import Business from "./Business";
-
-import Invoices from "./Invoices";
-
-import Payroll from "./Payroll";
-
-import Certification from "./Certification";
-
-import Support from "./Support";
-
-import Reports from "./Reports";
-
-import Settings from "./Settings";
-
-import ActivityLog from "./ActivityLog";
-
-import AddBusiness from "./AddBusiness";
-
-import EditBusiness from "./EditBusiness";
-
-import ProcurementDashboard from "./ProcurementDashboard";
-
-import OperatorDashboard from "./OperatorDashboard";
-
-import VendorDashboard from "./VendorDashboard";
-
-import WorkforceDashboard from "./WorkforceDashboard";
-
-import Messages from "./Messages";
-
-import ClientDashboard from "./ClientDashboard";
-
-import Onboarding from "./Onboarding";
-
-import ClientOrders from "./ClientOrders";
-
-import ClientInvoices from "./ClientInvoices";
-
-import VendorOrders from "./VendorOrders";
-
-import VendorStaff from "./VendorStaff";
-
-import VendorInvoices from "./VendorInvoices";
-
-import VendorPerformance from "./VendorPerformance";
-
-import WorkforceShifts from "./WorkforceShifts";
-
-import WorkforceEarnings from "./WorkforceEarnings";
-
-import WorkforceProfile from "./WorkforceProfile";
-
-import UserManagement from "./UserManagement";
-
-import Home from "./Home";
-
-import VendorRateCard from "./VendorRateCard";
-
-import Permissions from "./Permissions";
-
-import WorkforceCompliance from "./WorkforceCompliance";
-
-import Teams from "./Teams";
-
-import CreateTeam from "./CreateTeam";
-
-import TeamDetails from "./TeamDetails";
-
-import VendorManagement from "./VendorManagement";
-
-import PartnerManagement from "./PartnerManagement";
-
-import EnterpriseManagement from "./EnterpriseManagement";
-
-import VendorOnboarding from "./VendorOnboarding";
-
-import SectorManagement from "./SectorManagement";
-
-import AddEnterprise from "./AddEnterprise";
-
-import AddSector from "./AddSector";
-
-import AddPartner from "./AddPartner";
-
-import EditVendor from "./EditVendor";
-
-import SmartVendorOnboarding from "./SmartVendorOnboarding";
-
-import InviteVendor from "./InviteVendor";
-
-import VendorCompliance from "./VendorCompliance";
-
-import EditPartner from "./EditPartner";
-
-import EditSector from "./EditSector";
-
-import EditEnterprise from "./EditEnterprise";
-
-import VendorRates from "./VendorRates";
-
-import VendorDocumentReview from "./VendorDocumentReview";
-
-import VendorMarketplace from "./VendorMarketplace";
-
-import RapidOrder from "./RapidOrder";
-
-import SmartScheduler from "./SmartScheduler";
-
-import StaffOnboarding from "./StaffOnboarding";
-
-import NotificationSettings from "./NotificationSettings";
-
-import TaskBoard from "./TaskBoard";
-
-import InvoiceDetail from "./InvoiceDetail";
-
-import InvoiceEditor from "./InvoiceEditor";
-
-//import api-docs-raw from "./api-docs-raw";
-
-import Tutorials from "./Tutorials";
-
-import Schedule from "./Schedule";
-
-import StaffAvailability from "./StaffAvailability";
-
-import WorkerShiftProposals from "./WorkerShiftProposals";
-
import { BrowserRouter as Router, Route, Routes, useLocation } from 'react-router-dom';
+// Auth components
+import ProtectedRoute from '@/components/auth/ProtectedRoute';
+import PublicRoute from '@/components/auth/PublicRoute';
+
+// Layout and pages
+import Layout from "./Layout.jsx";
+import Home from "./Home";
+import Login from "./Login";
+import Register from "./Register";
+import Dashboard from "./Dashboard";
+import StaffDirectory from "./StaffDirectory";
+import AddStaff from "./AddStaff";
+import EditStaff from "./EditStaff";
+import Events from "./Events";
+import CreateEvent from "./CreateEvent";
+import EditEvent from "./EditEvent";
+import EventDetail from "./EventDetail";
+import Business from "./Business";
+import Invoices from "./Invoices";
+import Payroll from "./Payroll";
+import Certification from "./Certification";
+import Support from "./Support";
+import Reports from "./Reports";
+import Settings from "./Settings";
+import ActivityLog from "./ActivityLog";
+import AddBusiness from "./AddBusiness";
+import EditBusiness from "./EditBusiness";
+import ProcurementDashboard from "./ProcurementDashboard";
+import OperatorDashboard from "./OperatorDashboard";
+import VendorDashboard from "./VendorDashboard";
+import WorkforceDashboard from "./WorkforceDashboard";
+import Messages from "./Messages";
+import ClientDashboard from "./ClientDashboard";
+import Onboarding from "./Onboarding";
+import ClientOrders from "./ClientOrders";
+import ClientInvoices from "./ClientInvoices";
+import VendorOrders from "./VendorOrders";
+import VendorStaff from "./VendorStaff";
+import VendorInvoices from "./VendorInvoices";
+import VendorPerformance from "./VendorPerformance";
+import WorkforceShifts from "./WorkforceShifts";
+import WorkforceEarnings from "./WorkforceEarnings";
+import WorkforceProfile from "./WorkforceProfile";
+import UserManagement from "./UserManagement";
+import VendorRateCard from "./VendorRateCard";
+import Permissions from "./Permissions";
+import WorkforceCompliance from "./WorkforceCompliance";
+import Teams from "./Teams";
+import CreateTeam from "./CreateTeam";
+import TeamDetails from "./TeamDetails";
+import VendorManagement from "./VendorManagement";
+import PartnerManagement from "./PartnerManagement";
+import EnterpriseManagement from "./EnterpriseManagement";
+import VendorOnboarding from "./VendorOnboarding";
+import SectorManagement from "./SectorManagement";
+import AddEnterprise from "./AddEnterprise";
+import AddSector from "./AddSector";
+import AddPartner from "./AddPartner";
+import EditVendor from "./EditVendor";
+import SmartVendorOnboarding from "./SmartVendorOnboarding";
+import InviteVendor from "./InviteVendor";
+import VendorCompliance from "./VendorCompliance";
+import EditPartner from "./EditPartner";
+import EditSector from "./EditSector";
+import EditEnterprise from "./EditEnterprise";
+import VendorRates from "./VendorRates";
+import VendorDocumentReview from "./VendorDocumentReview";
+import VendorMarketplace from "./VendorMarketplace";
+import RapidOrder from "./RapidOrder";
+import SmartScheduler from "./SmartScheduler";
+import StaffOnboarding from "./StaffOnboarding";
+import NotificationSettings from "./NotificationSettings";
+import TaskBoard from "./TaskBoard";
+import InvoiceDetail from "./InvoiceDetail";
+import InvoiceEditor from "./InvoiceEditor";
+import Tutorials from "./Tutorials";
+import Schedule from "./Schedule";
+import StaffAvailability from "./StaffAvailability";
+import WorkerShiftProposals from "./WorkerShiftProposals";
+
const PAGES = {
-
- Dashboard: Dashboard,
-
- StaffDirectory: StaffDirectory,
-
- AddStaff: AddStaff,
-
- EditStaff: EditStaff,
-
- Events: Events,
-
- CreateEvent: CreateEvent,
-
- EditEvent: EditEvent,
-
- EventDetail: EventDetail,
-
- Business: Business,
-
- Invoices: Invoices,
-
- Payroll: Payroll,
-
- Certification: Certification,
-
- Support: Support,
-
- Reports: Reports,
-
- Settings: Settings,
-
- ActivityLog: ActivityLog,
-
- AddBusiness: AddBusiness,
-
- EditBusiness: EditBusiness,
-
- ProcurementDashboard: ProcurementDashboard,
-
- OperatorDashboard: OperatorDashboard,
-
- VendorDashboard: VendorDashboard,
-
- WorkforceDashboard: WorkforceDashboard,
-
- Messages: Messages,
-
- ClientDashboard: ClientDashboard,
-
- Onboarding: Onboarding,
-
- ClientOrders: ClientOrders,
-
- ClientInvoices: ClientInvoices,
-
- VendorOrders: VendorOrders,
-
- VendorStaff: VendorStaff,
-
- VendorInvoices: VendorInvoices,
-
- VendorPerformance: VendorPerformance,
-
- WorkforceShifts: WorkforceShifts,
-
- WorkforceEarnings: WorkforceEarnings,
-
- WorkforceProfile: WorkforceProfile,
-
- UserManagement: UserManagement,
-
- Home: Home,
-
- VendorRateCard: VendorRateCard,
-
- Permissions: Permissions,
-
- WorkforceCompliance: WorkforceCompliance,
-
- Teams: Teams,
-
- CreateTeam: CreateTeam,
-
- TeamDetails: TeamDetails,
-
- VendorManagement: VendorManagement,
-
- PartnerManagement: PartnerManagement,
-
- EnterpriseManagement: EnterpriseManagement,
-
- VendorOnboarding: VendorOnboarding,
-
- SectorManagement: SectorManagement,
-
- AddEnterprise: AddEnterprise,
-
- AddSector: AddSector,
-
- AddPartner: AddPartner,
-
- EditVendor: EditVendor,
-
- SmartVendorOnboarding: SmartVendorOnboarding,
-
- InviteVendor: InviteVendor,
-
- VendorCompliance: VendorCompliance,
-
- EditPartner: EditPartner,
-
- EditSector: EditSector,
-
- EditEnterprise: EditEnterprise,
-
- VendorRates: VendorRates,
-
- VendorDocumentReview: VendorDocumentReview,
-
- VendorMarketplace: VendorMarketplace,
-
- RapidOrder: RapidOrder,
-
- SmartScheduler: SmartScheduler,
-
- StaffOnboarding: StaffOnboarding,
-
- NotificationSettings: NotificationSettings,
-
- TaskBoard: TaskBoard,
-
- InvoiceDetail: InvoiceDetail,
-
- InvoiceEditor: InvoiceEditor,
-
- //api-docs-raw: api-docs-raw,
-
- Tutorials: Tutorials,
-
- Schedule: Schedule,
-
- StaffAvailability: StaffAvailability,
-
- WorkerShiftProposals: WorkerShiftProposals,
-
-}
+ Dashboard,
+ StaffDirectory,
+ AddStaff,
+ EditStaff,
+ Events,
+ CreateEvent,
+ EditEvent,
+ EventDetail,
+ Business,
+ Invoices,
+ Payroll,
+ Certification,
+ Support,
+ Reports,
+ Settings,
+ ActivityLog,
+ AddBusiness,
+ EditBusiness,
+ ProcurementDashboard,
+ OperatorDashboard,
+ VendorDashboard,
+ WorkforceDashboard,
+ Messages,
+ ClientDashboard,
+ Onboarding,
+ ClientOrders,
+ ClientInvoices,
+ VendorOrders,
+ VendorStaff,
+ VendorInvoices,
+ VendorPerformance,
+ WorkforceShifts,
+ WorkforceEarnings,
+ WorkforceProfile,
+ UserManagement,
+ Home,
+ VendorRateCard,
+ Permissions,
+ WorkforceCompliance,
+ Teams,
+ CreateTeam,
+ TeamDetails,
+ VendorManagement,
+ PartnerManagement,
+ EnterpriseManagement,
+ VendorOnboarding,
+ SectorManagement,
+ AddEnterprise,
+ AddSector,
+ AddPartner,
+ EditVendor,
+ SmartVendorOnboarding,
+ InviteVendor,
+ VendorCompliance,
+ EditPartner,
+ EditSector,
+ EditEnterprise,
+ VendorRates,
+ VendorDocumentReview,
+ VendorMarketplace,
+ RapidOrder,
+ SmartScheduler,
+ StaffOnboarding,
+ NotificationSettings,
+ TaskBoard,
+ InvoiceDetail,
+ InvoiceEditor,
+ Tutorials,
+ Schedule,
+ StaffAvailability,
+ WorkerShiftProposals,
+};
function _getCurrentPage(url) {
- if (url.endsWith('/')) {
- url = url.slice(0, -1);
- }
- let urlLastPart = url.split('/').pop();
- if (urlLastPart.includes('?')) {
- urlLastPart = urlLastPart.split('?')[0];
- }
-
- const pageName = Object.keys(PAGES).find(page => page.toLowerCase() === urlLastPart.toLowerCase());
- return pageName || Object.keys(PAGES)[0];
+ if (url.endsWith('/')) url = url.slice(0, -1);
+ let last = url.split('/').pop();
+ if (last.includes('?')) last = last.split('?')[0];
+ const pageName = Object.keys(PAGES).find(p => p.toLowerCase() === last.toLowerCase());
+ return pageName || 'Home'; // Default to Home
}
-// Create a wrapper component that uses useLocation inside the Router context
-function PagesContent() {
+
+function AppRoutes() {
const location = useLocation();
const currentPage = _getCurrentPage(location.pathname);
-
+
return (
-
-
-
- } />
-
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
- } />
-
-
-
+
+ {/* Public Routes */}
+ } />
+ } />
+
+ {/* Private Routes */}
+
+
+
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+
+
+
+ } />
+
);
}
export default function Pages() {
return (
-
+
);
}
\ No newline at end of file
From 6c574651735c6ef816ecf4df00d1ef3cb89a1923 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Salazar?=
<73718835+joshrs23@users.noreply.github.com>
Date: Fri, 28 Nov 2025 14:29:11 -0500
Subject: [PATCH 06/15] adding logout
---
frontend-web/src/pages/Layout.jsx | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/frontend-web/src/pages/Layout.jsx b/frontend-web/src/pages/Layout.jsx
index 1c5ca921..a5e5a21f 100644
--- a/frontend-web/src/pages/Layout.jsx
+++ b/frontend-web/src/pages/Layout.jsx
@@ -4,6 +4,8 @@ import { Link, useLocation, useNavigate } from "react-router-dom";
import { createPageUrl } from "@/utils";
import { base44 } from "@/api/base44Client";
import { useQuery } from "@tanstack/react-query";
+import { auth } from "@/firebase";
+import { signOut } from "firebase/auth";
import {
Users, LayoutDashboard, UserPlus, Calendar, Briefcase, FileText,
DollarSign, Award, HelpCircle, BarChart3, Activity, Menu, MessageSquare,
@@ -279,7 +281,7 @@ export default function Layout({ children }) {
const userInitial = userName.charAt(0).toUpperCase();
const handleLogout = () => {
- base44.auth.logout();
+ signOut(auth);
};
const handleRefresh = () => {
@@ -482,6 +484,10 @@ export default function Layout({ children }) {
My Profile
+
+
+ Logout
+
From aaa7aa98d9ed0845c0587c0221c29c2a5ac159e0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Salazar?=
<73718835+joshrs23@users.noreply.github.com>
Date: Fri, 28 Nov 2025 16:00:49 -0500
Subject: [PATCH 07/15] modification id for user
---
dataconnect/connector/user/mutations.gql | 6 +++---
dataconnect/connector/user/queries.gql | 2 +-
dataconnect/schema/user.gql | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/dataconnect/connector/user/mutations.gql b/dataconnect/connector/user/mutations.gql
index f0da8002..eeedba82 100644
--- a/dataconnect/connector/user/mutations.gql
+++ b/dataconnect/connector/user/mutations.gql
@@ -1,5 +1,5 @@
mutation CreateUser(
- $id: UUID!, # Firebase UID
+ $id: String!, # Firebase UID
$email: String!,
$fullName: String!,
$role: UserBaseRole!,
@@ -17,7 +17,7 @@ mutation CreateUser(
}
mutation UpdateUser(
- $id: UUID!,
+ $id: String!,
$email: String,
$fullName: String,
$role: UserBaseRole,
@@ -35,7 +35,7 @@ mutation UpdateUser(
}
mutation DeleteUser(
- $id: UUID!
+ $id: String!
) @auth(level: USER) {
user_delete(id: $id)
}
diff --git a/dataconnect/connector/user/queries.gql b/dataconnect/connector/user/queries.gql
index 6675c691..417860bf 100644
--- a/dataconnect/connector/user/queries.gql
+++ b/dataconnect/connector/user/queries.gql
@@ -11,7 +11,7 @@ query listUsers @auth(level: USER) {
}
query getUserById(
- $id: UUID!
+ $id: String!
) @auth(level: USER) {
user(id: $id) {
id
diff --git a/dataconnect/schema/user.gql b/dataconnect/schema/user.gql
index b5982534..ec927890 100644
--- a/dataconnect/schema/user.gql
+++ b/dataconnect/schema/user.gql
@@ -4,7 +4,7 @@ enum UserBaseRole {
}
type User @table(name: "users") {
- id: UUID! # user_id / uid de Firebase
+ id: String! # user_id / uid de Firebase
email: String!
fullName: String!
role: UserBaseRole!
From 4356e7d02cd5a4b47b8af9ab8c60d1f0f1e8f322 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Salazar?=
<73718835+joshrs23@users.noreply.github.com>
Date: Mon, 1 Dec 2025 09:48:28 -0500
Subject: [PATCH 08/15] solving problems for missing data in the from
---
dataconnect/connector/event/queries.gql | 2 ++
dataconnect/connector/user/queries.gql | 2 ++
2 files changed, 4 insertions(+)
diff --git a/dataconnect/connector/event/queries.gql b/dataconnect/connector/event/queries.gql
index c8c1c98b..3fe4233e 100644
--- a/dataconnect/connector/event/queries.gql
+++ b/dataconnect/connector/event/queries.gql
@@ -35,6 +35,7 @@ query listEvents @auth(level: USER) {
notes
requested
assignedStaff
+ createdBy
}
}
@@ -143,5 +144,6 @@ query filterEvents(
notes
requested
assignedStaff
+ createdBy
}
}
diff --git a/dataconnect/connector/user/queries.gql b/dataconnect/connector/user/queries.gql
index 417860bf..d761fdc6 100644
--- a/dataconnect/connector/user/queries.gql
+++ b/dataconnect/connector/user/queries.gql
@@ -23,12 +23,14 @@ query getUserById(
}
query filterUsers(
+ $id: String,
$email: String,
$role: UserBaseRole,
$userRole: String
) @auth(level: USER) {
users(
where: {
+ id: { eq: $id }
email: { eq: $email }
role: { eq: $role }
userRole: { eq: $userRole }
From fc31fbd4a3a7709e62594ec2aa84253b77efebc6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Salazar?=
<73718835+joshrs23@users.noreply.github.com>
Date: Mon, 1 Dec 2025 09:49:35 -0500
Subject: [PATCH 09/15] important configuration for dataconnect and firebase
---
frontend-web/src/api/client.js | 22 ++
frontend-web/src/api/krowSDK.js | 466 ++++++++++++++++++++++++++++++++
2 files changed, 488 insertions(+)
create mode 100644 frontend-web/src/api/client.js
create mode 100644 frontend-web/src/api/krowSDK.js
diff --git a/frontend-web/src/api/client.js b/frontend-web/src/api/client.js
new file mode 100644
index 00000000..e63a00f7
--- /dev/null
+++ b/frontend-web/src/api/client.js
@@ -0,0 +1,22 @@
+import axios from "axios";
+import { auth } from "../firebase";
+
+const apiClient = axios.create({
+ baseURL: import.meta.env.VITE_API_BASE_URL, // You will need to add this to your .env file
+});
+
+apiClient.interceptors.request.use(
+ async (config) => {
+ const user = auth.currentUser;
+ if (user) {
+ const token = await user.getIdToken();
+ config.headers.Authorization = `Bearer ${token}`;
+ }
+ return config;
+ },
+ (error) => {
+ return Promise.reject(error);
+ }
+);
+
+export default apiClient;
\ No newline at end of file
diff --git a/frontend-web/src/api/krowSDK.js b/frontend-web/src/api/krowSDK.js
new file mode 100644
index 00000000..45d6c64f
--- /dev/null
+++ b/frontend-web/src/api/krowSDK.js
@@ -0,0 +1,466 @@
+import apiClient from './client';
+import { auth, dataConnect } from '../firebase';
+import { signOut } from 'firebase/auth';
+
+import * as dcSdk from '@dataconnect/generated'; // listEvents, createEvent, etc.
+
+// --- Auth Module ---
+const authModule = {
+ /**
+ * Fetches the currently authenticated user's profile from the backend.
+ * @returns {Promise