Client Central Application
Client Central is a proof-of-concept Next.js application designed to provide Charles Schwab representatives with streamlined client management tools and information access. This internal application demonstrates modern React patterns and Adobe Spectrum design system integration while serving as a prototype for representative-facing client interaction tools.
Overview
- Application:
apps/client-central - Port: 3005
- Version: 1.0.12
- Framework: Next.js 15.3.2 with App Router
- Purpose: Representative client management proof-of-concept
- Access: Internal representative tools and client data management
Key Features
- Client Search: Real-time client lookup and information retrieval
- Client Information Display: Comprehensive client data presentation
- Representative Tools: Internal tools for client management workflows
- Account Overview: Client account status and overview information
- Notes Management: Client interaction notes and history tracking
- Context-Based Navigation: Dynamic content based on selected clients
- Adobe Spectrum Integration: Consistent design system implementation
Technical Architecture
Framework Stack
| Technology | Version | Purpose |
|---|---|---|
| Next.js | 15.3.2 | React framework with App Router and server components |
| React | 19.1.0 | Component library with React Aria integration |
| TypeScript | 5.8.2 | Type safety and enhanced development experience |
| Adobe React Spectrum | 3.40.1 | Design system and component library |
| Sass | 1.86.1 | CSS preprocessing and styling enhancement |
Core Dependencies
{
"@adobe/react-spectrum": "^3.40.1",
"@react-aria/interactions": "3.22.2",
"@react-aria/menu": "3.15.3",
"@schwab/beacon-design-tokens": "^1.24.29",
"@schwab/fetch": "workspace:*",
"@schwab/ui": "workspace:*",
"@schwab/utilities": "workspace:*",
"@vercel/analytics": "^1.5.0",
"@vercel/edge-config": "^1.4.0",
"@vercel/toolbar": "^0.1.36",
"react-aria": "^3.38.1",
"react-stately": "^3.36.1"
}
Monorepo Integration
The application leverages internal Charles Schwab packages:
@schwab/ui: Shared React component library@schwab/fetch: HTTP client utilities and data fetching@schwab/utilities: Common utility functions and helpers@schwab/beacon-design-tokens: Charles Schwab design system tokens@schwab/mock-data: Mock data for development and testing
Directory Structure
apps/client-central/
├── src/
│ ├── app/ # App Router directory (Next.js 13+)
│ │ ├── @globalFooter/ # Parallel route for footer component
│ │ │ └── default.tsx # Default footer implementation
│ │ ├── @globalHeader/ # Parallel route for header component
│ │ │ └── default.tsx # Default header implementation
│ │ ├── api/ # API route handlers
│ │ │ ├── health-check/ # Application health monitoring
│ │ │ │ └── route.ts # Health check endpoint
│ │ │ └── nbc/ # NBC (New Business Center) API routes
│ │ ├── context/ # React Context providers
│ │ │ └── dataContext.tsx # Application data context
│ │ ├── rhome/ # Representative home components
│ │ │ ├── accountlist.tsx # Client account listing
│ │ │ ├── cashering.tsx # Cash management tools
│ │ │ ├── clientinfo.tsx # Client information display
│ │ │ ├── clientoverview.tsx# Client overview summary
│ │ │ ├── nbc.tsx # New Business Center integration
│ │ │ └── notes.tsx # Client notes management
│ │ ├── layout.tsx # Root layout with parallel routes
│ │ ├── loading.tsx # Loading state component
│ │ └── page.tsx # Main application page
│ └── middleware.ts # Next.js middleware configuration
├── public/ # Static assets
│ ├── favicon.ico # Application favicon
│ └── test-img.png # Test image asset
├── .allowlists/ # Security allowlist configurations
├── next.config.js # Next.js configuration
├── package.json # Package dependencies and scripts
├── postcss.config.js # PostCSS configuration
└── tsconfig.json # TypeScript configuration
Application Architecture
Parallel Routes Pattern
The application uses Next.js App Router parallel routes for layout composition:
export default async function RootLayout({
children,
globalHeader,
globalFooter,
}: {
children: React.ReactNode;
globalHeader: React.ReactNode;
globalFooter: React.ReactNode;
}) {
return (
<html lang="en">
<body>
{globalHeader}
<Suspense fallback={<Loading />}>
<DataProvider>{children}</DataProvider>
</Suspense>
{globalFooter}
</body>
</html>
);
}
Context-Driven State Management
export const DataContext = createContext({
name: 'Bill Taylor',
custId: '1',
setCustId: (custId: any) => {
console.log(custId);
},
setName: (name: any) => {
console.log(name);
},
});
export default function DataProvider({ children }) {
const [name, setName] = useState('Bill Taylor');
const [custId, setCustId] = useState('1');
return (
<DataContext.Provider value={{ name, custId, setCustId, setName }}>
{children}
</DataContext.Provider>
);
}
Adobe Spectrum Integration
return (
<Provider theme={defaultTheme} marginTop={0}>
<Grid
areas={['sidebar content', 'footer footer']}
columns={['1fr', '3fr']}
rows={['auto', 'auto']}
height="size-6000"
gap="size-100"
>
<View gridArea="sidebar">
<SearchField
id="Search"
label="Search"
labelPosition="side"
onSubmit={setSubmittedText}
onClear={clearScreen}
/>
</View>
</Grid>
</Provider>
);
Middleware Architecture
Cookie-Based Session Management
export function middleware(request) {
const response = NextResponse.next();
const isFirstVisit = !request.cookies.has('repId');
if (isFirstVisit) {
response.cookies.set('repId', 'rep1', {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'strict',
maxAge: 60 * 60 * 24 * 365, // 1 year
});
}
return response;
}
Request Filtering
export const config = {
matcher: [
'/((?!api|_next/static|_next/image|favicon.ico|bundle|Areas).*)',
],
};
Component Architecture
Client Information Display
export default function ClientInfo() {
let { name } = React.useContext(DataContext);
return (
<InlineAlert width={420} marginTop={10}>
<Heading level={1}>Identification Information</Heading>
<Content>
<Flex direction="column" gap="size-100">
<LabeledValue label="Name" value={name} />
<Divider size="S" />
<LabeledValue
label="Date of Birth"
value={name === 'Bill Taylor' ? new Date(1980, 10, 15) : new Date(1971, 2, 6)}
formatOptions={{ dateStyle: 'short' }}
/>
<LabeledValue
label="Driver's License"
value={name === 'Bill Taylor' ? 'CA-1234333' : 'TX-342244'}
/>
</Flex>
</Content>
</InlineAlert>
);
}
Security Configuration
Next.js Security Headers
async headers() {
return [
{
source: '/:path*',
headers: [
{
key: 'Strict-Transport-Security',
value: 'max-age=63072000; includeSubDomains; preload',
},
{ key: 'X-Frame-Options', value: 'SAMEORIGIN' },
{ key: 'Referrer-Policy', value: 'origin-when-cross-origin' },
{ key: 'X-Content-Type-Options', value: 'nosniff' },
],
},
];
}
CORS Configuration for APIs
{
source: '/api/:path*',
headers: [
{ key: 'Access-Control-Allow-Credentials', value: 'true' },
{ key: 'Access-Control-Allow-Origin', value: '*' },
{ key: 'Access-Control-Allow-Methods', value: 'GET,OPTIONS' },
{
key: 'Access-Control-Allow-Headers',
value: 'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version,x-vercel-protection-bypass,correlatorid,schwab-client-appid,schwab-client-channel,schwab-client-correlid,schwab-environment,schwab-environment-region',
},
],
}
Development Workflow
Local Development
# Install dependencies
pnpm install
# Start development server on port 3005
pnpm dev
# Build for production
pnpm build
# Build in test mode
pnpm build-testmode
# Start production server
pnpm start
# Type checking
pnpm type-check
# Code conformance checking
pnpm conformance
Package Transpilation
The application transpiles the complete Adobe React Spectrum ecosystem:
transpilePackages: [
'@adobe/react-spectrum',
'@react-spectrum/actiongroup',
'@react-spectrum/badge',
'@react-spectrum/breadcrumbs',
'@react-spectrum/button',
'@react-spectrum/buttongroup',
'@react-spectrum/calendar',
'@react-spectrum/checkbox',
// ... additional 30+ Spectrum packages
'@spectrum-icons/illustrations',
'@spectrum-icons/ui',
'@spectrum-icons/workflow',
]
API Architecture
Health Check Monitoring
export function GET() {
return new Response(JSON.stringify(getAppVersion(packageJSON.name)), {
status: 200,
});
}
Application Flow
Image Optimization
Remote Pattern Configuration
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'prospectsitecollection.uat-schwab.acsitefactory.com',
port: '',
pathname: '**',
},
{
protocol: 'https',
hostname: 'education.uat-schwab.acsitefactory.com',
port: '',
pathname: '**',
},
{
protocol: 'https',
hostname: 'education-uat.dev.schwab.tech',
port: '',
pathname: '**',
},
],
}
Representative Tools Features
Client Search and Selection
- Real-time Search: Dynamic client lookup with search field
- Context Switching: Seamless client context changes
- Default Clients: Pre-configured test clients for development
Client Information Management
| Component | Purpose | Features |
|---|---|---|
ClientInfo | Personal information display | Name, DOB, Driver's License |
ClientOverview | Account summary | Account status, balances, alerts |
AccountList | Account management | Multiple account display and selection |
Notes | Client interaction tracking | Add, edit, and view client notes |
Cashering | Transaction tools | Cash management and processing |
Business Center Integration
Testing and Quality Assurance
Development Dependencies
{
"@jest/globals": "^29.7.0",
"@schwab/mock-data": "workspace:*",
"@testing-library/react": "^16.2.0",
"@vercel-private/conformance": "1.12.4",
"jest-mock-extended": "^3.0.7",
"ts-node": "^10.9.2"
}
Code Quality Tools
- TypeScript: Strict type checking and IDE integration
- Vercel Conformance: Code quality and performance standards
- Jest: Unit testing framework
- React Testing Library: Component testing utilities
Performance Optimization
Next.js Configuration Features
const nextConfig = {
experimental: {
useCache: true, // Enable caching optimizations
},
reactStrictMode: true, // Enhanced development checks
trailingSlash: true, // Consistent URL structure
}
Vercel Integration
- Vercel Analytics: Performance monitoring and insights
- Speed Insights: Core Web Vitals tracking
- Edge Configuration: Dynamic configuration management
- Vercel Toolbar: Development and debugging tools
Common Use Cases
Representative Workflow
// 1. Representative searches for client
const handleClientSearch = (searchTerm: string) => {
setCustId(searchTerm);
setName(searchTerm === '1' ? 'Bill Taylor' : 'Fred Bloggs');
setShowChild(true);
};
// 2. Context updates trigger component re-renders
// 3. Client-specific tools become available
// 4. Representative performs client management tasks
Client Context Management
export default function ClientSpecificComponent() {
const { name, custId } = React.useContext(DataContext);
// Component automatically updates when client changes
return (
<InlineAlert>
<Heading>Client: {name}</Heading>
<Content>ID: {custId}</Content>
</InlineAlert>
);
}
Integration Patterns
Monorepo Package Integration
| Package | Integration | Purpose |
|---|---|---|
@schwab/ui | Component imports | Shared UI components |
@schwab/fetch | Data fetching | HTTP client utilities |
@schwab/utilities | Utility functions | Common business logic |
@schwab/beacon-design-tokens | Theming | Design system tokens |
External Service Integration
- Adobe Spectrum: Design system and accessibility features
- Vercel Platform: Deployment and performance monitoring
- Internal APIs: Client data and business services
Troubleshooting
Common Issues
| Issue | Cause | Solution |
|---|---|---|
| Port 3005 in use | Previous process running | Use kill script in dev command |
| Spectrum components not rendering | Missing Provider | Wrap components in Spectrum Provider |
| Context not updating | Missing context provider | Ensure DataProvider wraps components |
| TypeScript errors | Missing type definitions | Run pnpm type-check |
| Build failures | Package transpilation | Verify Next.js config transpilePackages |
Development Tips
Always wrap Spectrum components in a Provider with appropriate theme configuration for proper styling and accessibility.
Ensure all components using DataContext are wrapped by the DataProvider in the component tree.
Future Enhancements
- Real Client Data Integration: Connection to actual client management systems
- Enhanced Security: Role-based access control and authentication
- Advanced Search: Multi-criteria client search capabilities
- Workflow Automation: Streamlined representative task automation
- Mobile Optimization: Responsive design for tablet and mobile use
- Performance Analytics: Representative productivity metrics
This Client Central application serves as a valuable proof-of-concept for modern representative tools, demonstrating advanced React patterns, design system integration, and internal tool development best practices within the Charles Schwab technology ecosystem.