Skip to main content

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

TechnologyVersionPurpose
Next.js15.3.2React framework with App Router and server components
React19.1.0Component library with React Aria integration
TypeScript5.8.2Type safety and enhanced development experience
Adobe React Spectrum3.40.1Design system and component library
Sass1.86.1CSS preprocessing and styling enhancement

Core Dependencies

Key dependencies from package.json
{
"@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:

Root layout with parallel routes
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

Application data context
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

Spectrum component usage
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

Representative ID middleware
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

Middleware configuration
export const config = {
matcher: [
'/((?!api|_next/static|_next/image|favicon.ico|bundle|Areas).*)',
],
};

Component Architecture

Client Information Display

Client information component
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

Security headers configuration
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

API CORS configuration
{
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

Development commands
# 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:

Transpiled packages
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

Health check endpoint
export function GET() {
return new Response(JSON.stringify(getAppVersion(packageJSON.name)), {
status: 200,
});
}

Application Flow

Image Optimization

Remote Pattern Configuration

Image optimization settings
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

ComponentPurposeFeatures
ClientInfoPersonal information displayName, DOB, Driver's License
ClientOverviewAccount summaryAccount status, balances, alerts
AccountListAccount managementMultiple account display and selection
NotesClient interaction trackingAdd, edit, and view client notes
CasheringTransaction toolsCash management and processing

Business Center Integration

Testing and Quality Assurance

Development Dependencies

Testing and development tools
{
"@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

Performance optimizations
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

Typical representative interaction
// 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

Context-driven component updates
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

PackageIntegrationPurpose
@schwab/uiComponent importsShared UI components
@schwab/fetchData fetchingHTTP client utilities
@schwab/utilitiesUtility functionsCommon business logic
@schwab/beacon-design-tokensThemingDesign 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

IssueCauseSolution
Port 3005 in usePrevious process runningUse kill script in dev command
Spectrum components not renderingMissing ProviderWrap components in Spectrum Provider
Context not updatingMissing context providerEnsure DataProvider wraps components
TypeScript errorsMissing type definitionsRun pnpm type-check
Build failuresPackage transpilationVerify Next.js config transpilePackages

Development Tips

Adobe Spectrum

Always wrap Spectrum components in a Provider with appropriate theme configuration for proper styling and accessibility.

Context Usage

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.