Skip to main content
Glama
README.md7.28 kB
# Component Contracts **Date**: 2025-10-14 **Feature**: Production-Ready Dashboard with Design System **Phase**: 1 (Design & Contracts) ## Overview This directory contains TypeScript interface definitions (contracts) for all dashboard components. These contracts serve as design-time documentation and will guide implementation. --- ## Files ### `ui-components.ts` **Base UI component interfaces** from shadcn/ui: - Button (6 variants: default, primary, secondary, ghost, link, destructive) - Card (with Header, Title, Description, Content, Footer) - Input (text, email, password, number, tel, url) - Table (with sorting, pagination, custom rendering) - Dialog/Modal (with Header, Title, Description, Footer) - Skeleton (loading placeholders) - Alert (info, warning, error, success) - Badge (status indicators) - Select (dropdown) - Tooltip (contextual help) - Form (with validation) **Total**: 10+ base components --- ### `page-components.ts` **Page-specific component interfaces** for dashboard pages: **Usage Page**: - `MetricsSummary` - Display API requests, listing count, projected bill - `UsageChart` - 30-day historical API request trend (Recharts) - `UsageMetricCard` - Individual metric card **Billing Page**: - `BillingHistory` - Table of past invoices - `PaymentMethodCard` - Current payment method with update option **API Keys Page**: - `ApiKeyList` - Table of API keys with actions - `CreateApiKeyModal` - Modal for creating new API key - `ApiKeyCreatedDialog` - One-time display of new key **Settings Page**: - `HostawayCredentialsForm` - Update Hostaway API credentials - `OrganizationSettingsForm` - Update organization details **Layout Components**: - `DashboardNav` - Main navigation sidebar/header - `PageHeader` - Page title and breadcrumbs - `EmptyState` - Generic empty state - `ErrorState` - Generic error state - `LoadingState` - Generic loading state **Total**: 15+ page-specific components --- ### `data-types.ts` **Data structure types** for database entities and view models: **Database Entities** (from Supabase): - `Organization` - `OrganizationMember` - `HostawayCredentials` - `ApiKey` - `Subscription` - `UsageMetrics` - `AuditLog` **View Models** (aggregated data for pages): - `UsagePageData` - `BillingPageData` - `ApiKeysPageData` - `SettingsPageData` **Form Data Types**: - `ApiKeyFormData` - `HostawayCredentialsFormData` - `OrganizationFormData` **Error Types**: - `ApiError` - `ValidationError` **Loading State Types**: - `LoadingState<T>` - `MutationState` **Utility Types**: - `PaginationMeta` - `PaginatedResponse<T>` - `SortConfig<T>` **Chart Data Types**: - `UsageChartDataPoint` - `BillingChartDataPoint` **Context Types**: - `UserContext` - `OrganizationContext` - `DashboardContext` **Enums**: - `UserRole` - `SubscriptionStatus` - `InvoiceStatus` - `AuditAction` **Total**: 30+ type definitions --- ## Usage in Implementation ### 1. Import Base Components ```typescript import { Button } from '@/components/ui/button' import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card' ``` ### 2. Import Page Components ```typescript import { MetricsSummary } from '@/components/usage/metrics-summary' import { UsageChart } from '@/components/usage/usage-chart' ``` ### 3. Import Data Types ```typescript import type { UsagePageData, LoadingState } from '@/contracts/data-types' ``` ### 4. Use Interfaces in Component Props ```typescript // Example: Implementing MetricsSummary component import type { MetricsSummaryProps } from '@/contracts/page-components' export function MetricsSummary({ apiRequests, listingCount, projectedBill, billingPeriod, loading = false, error = null, }: MetricsSummaryProps) { // Component implementation } ``` --- ## Contract Principles ### 1. Type Safety All component props are strongly typed. No `any` types allowed. ### 2. Loading States All data-fetching components accept `loading?: boolean` prop to show skeleton loaders. ### 3. Error States All data-fetching components accept `error?: Error | null` prop to show error messages. ### 4. Optional Props Props with defaults (e.g., `variant`, `size`) are marked as optional with `?`. ### 5. Children Components that accept children use `children: ReactNode` type. ### 6. Event Handlers Event handlers use clear naming: `onClick`, `onChange`, `onSubmit`, `onRetry`. ### 7. Accessibility All interactive components support keyboard navigation and ARIA attributes (handled by Radix UI). --- ## Relationship to Implementation **These contracts are design-time documentation**, not runtime code. During implementation: 1. **shadcn/ui components** (Button, Card, etc.) will be installed via CLI and may have additional props not listed here. 2. **Page-specific components** (MetricsSummary, UsageChart, etc.) will be implemented using these contracts as the source of truth. 3. **Data types** will be used throughout the codebase for type-safe data fetching and state management. --- ## Examples ### Example 1: Button Usage ```tsx import { Button } from '@/components/ui/button' <Button variant="primary" size="lg" onClick={handleSubmit}> Submit </Button> <Button variant="destructive" disabled> Delete </Button> ``` ### Example 2: Card Usage ```tsx import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card' <Card> <CardHeader> <CardTitle>API Usage</CardTitle> </CardHeader> <CardContent> <p>1,234 requests this month</p> </CardContent> </Card> ``` ### Example 3: MetricsSummary Usage ```tsx import { MetricsSummary } from '@/components/usage/metrics-summary' <MetricsSummary apiRequests={1234} listingCount={56} projectedBill={12.50} billingPeriod={{ start: new Date('2025-10-01'), end: new Date('2025-10-31'), }} loading={false} error={null} /> ``` ### Example 4: Data Fetching with LoadingState ```tsx import type { UsagePageData, LoadingState } from '@/contracts/data-types' const [state, setState] = useState<LoadingState<UsagePageData>>({ data: null, isLoading: true, error: null, }) useEffect(() => { fetchUsageData(orgId) .then(data => setState({ data, isLoading: false, error: null })) .catch(error => setState({ data: null, isLoading: false, error })) }, [orgId]) if (state.isLoading) return <LoadingState /> if (state.error) return <ErrorState error={state.error} onRetry={refetch} /> if (!state.data) return <EmptyState title="No data available" /> return <MetricsSummary {...state.data.currentMonthMetrics} /> ``` --- ## Validation To verify contracts are being followed during implementation: 1. **TypeScript Compiler**: All implementations must pass `tsc --noEmit` with no errors 2. **ESLint**: Use `@typescript-eslint/consistent-type-definitions` rule 3. **Code Review**: Verify all component props match contract interfaces --- ## Next Steps After contracts are defined: 1. ✅ Contracts created and documented 2. → Run `/speckit.tasks` to generate implementation tasks 3. → Implement shadcn/ui base components 4. → Implement page-specific components using contracts 5. → Run TypeScript compiler to verify type safety --- **Status**: ✅ **CONTRACTS COMPLETE** **Date**: 2025-10-14 **Next Phase**: Task Generation (`/speckit.tasks`)

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/darrentmorgan/hostaway-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server