mirror of
https://github.com/Sea-Haven-Industries/proposal-system.git
synced 2026-10-04 19:32:02 +00:00
pages: users empty state card, form max-width, table display improvements
This commit is contained in:
parent
cfee6690c0
commit
0c8ab31282
3 changed files with 37 additions and 15 deletions
|
|
@ -1,5 +1,9 @@
|
||||||
import { Routes, Route, Navigate } from 'react-router-dom';
|
import { Routes, Route, Navigate } from 'react-router-dom';
|
||||||
import { Box, Toolbar, Typography } from '@mui/material';
|
import { useSelector } from 'react-redux';
|
||||||
|
import { Box, Button, Card, CardContent, Toolbar, Typography } from '@mui/material';
|
||||||
|
import PeopleIcon from '@mui/icons-material/People';
|
||||||
|
import { selectSidebarOpen } from './app/slices/uiSlice';
|
||||||
|
import type { RootState } from './app/store';
|
||||||
import ProtectedRoute, { RoleGuard } from './components/ProtectedRoute';
|
import ProtectedRoute, { RoleGuard } from './components/ProtectedRoute';
|
||||||
import Topbar from './components/Topbar';
|
import Topbar from './components/Topbar';
|
||||||
import Sidebar from './components/Sidebar';
|
import Sidebar from './components/Sidebar';
|
||||||
|
|
@ -11,7 +15,11 @@ import ProposalDetailPage from './pages/proposals/detail/ProposalDetailPage';
|
||||||
import ProposalListPage from './pages/proposals/list/ProposalListPage';
|
import ProposalListPage from './pages/proposals/list/ProposalListPage';
|
||||||
import AdminDashboard from './pages/admin/dashboard/AdminDashboard';
|
import AdminDashboard from './pages/admin/dashboard/AdminDashboard';
|
||||||
import AdminWorkspace from './pages/admin/workspace/AdminWorkspace';
|
import AdminWorkspace from './pages/admin/workspace/AdminWorkspace';
|
||||||
|
import { DRAWER_WIDTH } from './constants';
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
|
const sidebarOpen = useSelector((state: RootState) => selectSidebarOpen(state));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/login" element={<LoginPage />} />
|
<Route path="/login" element={<LoginPage />} />
|
||||||
|
|
@ -29,6 +37,8 @@ export default function App() {
|
||||||
sx={{
|
sx={{
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
p: 1.25,
|
p: 1.25,
|
||||||
|
ml: sidebarOpen ? `${DRAWER_WIDTH}px` : 0,
|
||||||
|
transition: 'margin-left 250ms ease',
|
||||||
minHeight: '100vh',
|
minHeight: '100vh',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
@ -46,13 +56,18 @@ export default function App() {
|
||||||
<Route path="/admin/users" element={
|
<Route path="/admin/users" element={
|
||||||
<RoleGuard roles={['SysAdmin']}>
|
<RoleGuard roles={['SysAdmin']}>
|
||||||
<Box sx={{ display: 'flex', justifyContent: 'center', pt: 6 }}>
|
<Box sx={{ display: 'flex', justifyContent: 'center', pt: 6 }}>
|
||||||
<Box sx={{ textAlign: 'center', maxWidth: 400 }}>
|
<Card sx={{ maxWidth: 520, p: 4, textAlign: 'center' }}>
|
||||||
<Typography variant="h5" sx={{ mb: 1 }}>User Management</Typography>
|
<CardContent>
|
||||||
<Typography variant="h6" color="text.secondary" sx={{ mb: 2, fontWeight: 400 }}>Coming Soon</Typography>
|
<PeopleIcon sx={{ fontSize: 48, color: '#94A3B8', mb: 2 }} />
|
||||||
<Typography variant="body2" color="text.secondary" sx={{ mb: 3 }}>
|
<Typography variant="h5" sx={{ mb: 1 }}>User Management</Typography>
|
||||||
Users and roles are currently managed in Cognito. Contact the system administrator to update access.
|
<Typography variant="body1" color="text.secondary" sx={{ mb: 3 }}>
|
||||||
</Typography>
|
Users and roles are currently managed in AWS Cognito. Contact the system administrator to update access.
|
||||||
</Box>
|
</Typography>
|
||||||
|
<Button variant="outlined" size="large">
|
||||||
|
View Access Roles
|
||||||
|
</Button>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
</Box>
|
</Box>
|
||||||
</RoleGuard>
|
</RoleGuard>
|
||||||
} />
|
} />
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,7 @@ export default function ProposalFormPage() {
|
||||||
}, [form.workOrderNumber, form.customerAddress, form.serviceCategory, form.scopeOfWork, customCategory]);
|
}, [form.workOrderNumber, form.customerAddress, form.serviceCategory, form.scopeOfWork, customCategory]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box sx={{ maxWidth: 1200 }}>
|
||||||
<Typography variant="h5" sx={{ mb: 3 }}>
|
<Typography variant="h5" sx={{ mb: 3 }}>
|
||||||
New Proposal Request
|
New Proposal Request
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ import SearchIcon from '@mui/icons-material/Search';
|
||||||
import AddCircleIcon from '@mui/icons-material/AddCircle';
|
import AddCircleIcon from '@mui/icons-material/AddCircle';
|
||||||
import { usePaginatedList } from '../../../hooks/usePaginatedList';
|
import { usePaginatedList } from '../../../hooks/usePaginatedList';
|
||||||
import { proposalsApi, type ProposalListItem } from '../../../lib/api/proposals';
|
import { proposalsApi, type ProposalListItem } from '../../../lib/api/proposals';
|
||||||
import { STATUS_CHIP_STYLES } from '../../../constants';
|
import { STATUS_COLORS } from '../../../constants';
|
||||||
import { formatCurrency, formatDate } from '../../../lib/format';
|
import { formatBidAmount, formatDate, formatDateFull } from '../../../lib/format';
|
||||||
import { useDocumentTitle } from '../../../hooks/useDocumentTitle';
|
import { useDocumentTitle } from '../../../hooks/useDocumentTitle';
|
||||||
|
|
||||||
export default function ProposalListPage() {
|
export default function ProposalListPage() {
|
||||||
|
|
@ -112,7 +112,7 @@ export default function ProposalListPage() {
|
||||||
sx={{ cursor: 'pointer' }}
|
sx={{ cursor: 'pointer' }}
|
||||||
onClick={() => navigate(`/proposals/${row.id}`)}
|
onClick={() => navigate(`/proposals/${row.id}`)}
|
||||||
>
|
>
|
||||||
<TableCell sx={{ fontWeight: 600 }}>{row.proposalNumber}</TableCell>
|
<TableCell sx={{ fontWeight: 700 }}>{row.proposalNumber}</TableCell>
|
||||||
<TableCell>{row.customerName}</TableCell>
|
<TableCell>{row.customerName}</TableCell>
|
||||||
<TableCell>{row.workOrderNumber}</TableCell>
|
<TableCell>{row.workOrderNumber}</TableCell>
|
||||||
<TableCell>{row.serviceCategory}</TableCell>
|
<TableCell>{row.serviceCategory}</TableCell>
|
||||||
|
|
@ -121,11 +121,18 @@ export default function ProposalListPage() {
|
||||||
<Chip
|
<Chip
|
||||||
label={row.status}
|
label={row.status}
|
||||||
size="small"
|
size="small"
|
||||||
sx={STATUS_CHIP_STYLES[row.status]}
|
color={STATUS_COLORS[row.status] || 'default'}
|
||||||
/>
|
/>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell align="right">{formatCurrency(row.totalBidAmount)}</TableCell>
|
<TableCell align="right">
|
||||||
<TableCell>{formatDate(row.submittedAt)}</TableCell>
|
{row.totalBidAmount > 0
|
||||||
|
? formatBidAmount(row.totalBidAmount)
|
||||||
|
: <Typography variant="body2" component="span" sx={{ color: '#64748B' }}>Not priced</Typography>
|
||||||
|
}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<span title={formatDateFull(row.submittedAt)}>{formatDate(row.submittedAt)}</span>
|
||||||
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
))}
|
||||||
{!loading && rows.length === 0 && (
|
{!loading && rows.length === 0 && (
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue