From 1e1e29ad996874b5363548c62ca35583e0e70e1a Mon Sep 17 00:00:00 2001 From: Krao Hasanee Date: Fri, 27 Mar 2026 00:04:49 -0400 Subject: [PATCH] Add client company dashboard as landing page Co-Authored-By: Claude Sonnet 4.6 --- src/App.jsx | 2 + src/components/Layout.jsx | 1 + src/pages/Login.jsx | 2 +- src/pages/client/MyCompany.jsx | 100 +++++++++++++++++++++++++++++++++ 4 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 src/pages/client/MyCompany.jsx diff --git a/src/App.jsx b/src/App.jsx index 2fbd713..f5429f3 100755 --- a/src/App.jsx +++ b/src/App.jsx @@ -17,6 +17,7 @@ import CreateInvoice from './pages/team/CreateInvoice'; import InvoiceDetail from './pages/team/InvoiceDetail'; import Settings from './pages/Settings'; +import MyCompany from './pages/client/MyCompany'; import MyRequests from './pages/client/MyRequests'; import MyProjects from './pages/client/MyProjects'; import MyProjectDetail from './pages/client/MyProjectDetail'; @@ -45,6 +46,7 @@ export default function App() { } /> + } /> } /> } /> } /> diff --git a/src/components/Layout.jsx b/src/components/Layout.jsx index 18a817c..deaf16a 100755 --- a/src/components/Layout.jsx +++ b/src/components/Layout.jsx @@ -25,6 +25,7 @@ function ClientNav({ onNav }) {
My Work
{[ + { to: '/my-company', label: 'Company' }, { to: '/my-projects', label: 'Projects' }, { to: '/my-invoices', label: 'Invoices' }, ].map(({ to, label }) => ( diff --git a/src/pages/Login.jsx b/src/pages/Login.jsx index 9417a49..501d9ac 100755 --- a/src/pages/Login.jsx +++ b/src/pages/Login.jsx @@ -14,7 +14,7 @@ export default function Login() { useEffect(() => { if (currentUser) { - navigate(currentUser.role === 'team' ? '/dashboard' : '/my-projects', { replace: true }); + navigate(currentUser.role === 'team' ? '/dashboard' : '/my-company', { replace: true }); } }, [currentUser, navigate]); diff --git a/src/pages/client/MyCompany.jsx b/src/pages/client/MyCompany.jsx new file mode 100644 index 0000000..27115ab --- /dev/null +++ b/src/pages/client/MyCompany.jsx @@ -0,0 +1,100 @@ +import { useState, useEffect } from 'react'; +import { Link } from 'react-router-dom'; +import Layout from '../../components/Layout'; +import { supabase } from '../../lib/supabase'; +import { useAuth } from '../../context/AuthContext'; + +export default function MyCompany() { + const { currentUser } = useAuth(); + const company = currentUser?.company; + const [members, setMembers] = useState([]); + const [stats, setStats] = useState({ projects: 0, active: 0 }); + const [loading, setLoading] = useState(true); + + useEffect(() => { + if (!company?.id) { setLoading(false); return; } + async function load() { + const [{ data: m }, { data: p }, { data: t }] = await Promise.all([ + supabase.from('profiles').select('id, name, email').eq('company_id', company.id).eq('role', 'client'), + supabase.from('projects').select('id').eq('company_id', company.id), + supabase.from('tasks').select('id, status, project_id'), + ]); + setMembers(m || []); + const projectIds = (p || []).map(pr => pr.id); + const activeTasks = (t || []).filter(task => projectIds.includes(task.project_id) && task.status !== 'client_approved'); + setStats({ projects: (p || []).length, active: activeTasks.length }); + setLoading(false); + } + load(); + }, [company?.id]); + + if (loading) return

Loading...

; + + return ( + +
+
+
{company?.name || 'Your Company'}
+
+ {[company?.phone, company?.address].filter(Boolean).join(' · ') || 'No contact info on file'} +
+
+ + New Request +
+ + {/* Stats */} +
+
+
{stats.projects}
+
Projects
+
+
+
{stats.active}
+
Active Jobs
+
+
+
{members.length}
+
Team Members
+
+
+ + {/* Team members */} +
+
People
+ {members.length === 0 ? ( +

No members found.

+ ) : ( +
+ {members.map((member, i) => ( +
+
+ {member.name?.split(' ').map(n => n[0]).join('').toUpperCase().slice(0, 2)} +
+
+
+ {member.name} + {member.id === currentUser.id && ( + You + )} +
+
{member.email || '—'}
+
+
+ ))} +
+ )} +
+
+ ); +}