mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-30 23:14:37 +00:00
* ran prettier * Refactor ESLint configuration to use ES module syntax and enhance TypeScript support - Converted CommonJS `require` statements to ES module `import` syntax for better compatibility with modern JavaScript. - Added new paths to ignore in ESLint configuration to exclude additional directories. - Updated TypeScript file patterns to be more specific, improving linting accuracy. - Adjusted React hooks rules to allow certain patterns, enhancing flexibility in component design. These changes improve the maintainability and clarity of the ESLint configuration, aligning it with current best practices. * Refactor ESLint configuration to use ES module syntax and enhance TypeScript support - Converted CommonJS `require` statements to ES module `import` syntax for better compatibility with modern JavaScript. - Added new paths to ignore in ESLint configuration to exclude additional directories. - Updated TypeScript file patterns to be more specific, improving linting accuracy. - Introduced new React hooks rules and adjusted existing rules for better adherence to best practices. - Made minor adjustments to import statements across various files for consistency and clarity. These changes improve the overall linting setup and ensure better code quality across the project. * Refactor import statements across multiple files for consistency - Updated import statements to use TypeScript's `type` syntax for type imports, enhancing clarity and consistency across the codebase. - Consolidated imports from the same module into single statements, improving readability and maintainability. These changes streamline the code structure and align with best practices for TypeScript imports. * Refactor import statements in memory manager for improved clarity - Updated import statements to consolidate type imports and enhance readability. - Removed redundant imports, streamlining the code structure in the memory manager file. These changes align with best practices for TypeScript imports and improve maintainability. * Add Husky for pre-commit and pre-push hooks - Introduced Husky to manage Git hooks, enhancing the development workflow. - Added pre-commit and pre-push scripts to enforce code formatting and linting checks before commits and pushes. - Updated package.json to include Husky as a dependency and added a prepare script for setup. These changes improve code quality and ensure adherence to formatting and linting standards during the development process. * Refactor import statements for improved clarity and consistency - Updated import statements across multiple files to consolidate type imports and enhance readability. - Adjusted the order of imports for better organization and alignment with best practices in TypeScript. These changes streamline the code structure and improve maintainability throughout the project. * ran formatter * Refactor import statements and improve code formatting across multiple files - Consolidated and reordered import statements for better clarity and consistency in `SkillsGrid.tsx`, `SkillProvider.tsx`, and `index.ts`. - Enhanced readability by adjusting formatting and removing redundant lines. - These changes align with best practices for TypeScript imports and improve overall maintainability of the codebase. * Refactor and optimize code in multiple components - Removed redundant properties from the `STATUS_DISPLAY` object in `SkillsGrid.tsx` to streamline status handling. - Consolidated import statements in `SettingsModal.tsx` for improved organization. - Simplified state management and error handling in `BillingPanel.tsx`, enhancing performance and readability. - Added `REHYDRATE` import to `index.ts` for better state persistence management. These changes improve code clarity, maintainability, and align with best practices in TypeScript development. * Consolidate import statements in SettingsModal.tsx for improved organization * Add Prettier and ESLint checks to typecheck workflow - Integrated a Prettier formatting check to ensure code style consistency. - Added an ESLint step to enforce code quality and catch potential issues. - These enhancements improve the development workflow by automating formatting and linting checks during the typecheck process. * Add activeSkillDescription state to ConnectionsPanel and ConnectStep - Introduced activeSkillDescription state in both ConnectionsPanel and ConnectStep components to store and manage skill descriptions. - Updated the SkillSetupModal to accept skillDescription as a prop, enhancing the modal's functionality and data handling. These changes improve the user experience by providing more detailed information about skills during the connection setup process. * Enhance pre-push hook to include TypeScript compile check - Added a TypeScript compile check to the pre-push script, ensuring that code compiles successfully before pushing. - Updated error handling to include compile errors alongside formatting and linting issues, providing clearer feedback to developers. These changes improve the reliability of the codebase by preventing non-compiling code from being pushed. * Update GitHub workflows for pull request handling and publishing logic - Modified the package-and-publish workflow to support pull request events, ensuring proper handling of branches. - Adjusted the SHOULD_PUBLISH environment variable to differentiate between pull requests and main branch events. - Updated the pr-protection workflow to focus solely on the main branch, removing references to the master branch. These changes enhance the CI/CD process by refining branch handling and improving clarity in workflow conditions.
514 lines
10 KiB
Markdown
514 lines
10 KiB
Markdown
# Components
|
|
|
|
Reusable React components organized by feature.
|
|
|
|
## Component Structure
|
|
|
|
```
|
|
components/
|
|
├── Route Guards
|
|
│ ├── ProtectedRoute.tsx
|
|
│ ├── PublicRoute.tsx
|
|
│ └── DefaultRedirect.tsx
|
|
│
|
|
├── Authentication
|
|
│ └── TelegramLoginButton.tsx
|
|
│
|
|
├── Connection Status
|
|
│ ├── ConnectionIndicator.tsx
|
|
│ ├── TelegramConnectionIndicator.tsx
|
|
│ ├── TelegramConnectionModal.tsx
|
|
│ └── GmailConnectionIndicator.tsx
|
|
│
|
|
├── Onboarding
|
|
│ ├── ProgressIndicator.tsx
|
|
│ └── LottieAnimation.tsx
|
|
│
|
|
├── Settings Modal (16 files)
|
|
│ ├── SettingsModal.tsx
|
|
│ ├── SettingsLayout.tsx
|
|
│ ├── SettingsHome.tsx
|
|
│ ├── panels/
|
|
│ ├── components/
|
|
│ └── hooks/
|
|
│
|
|
└── Development
|
|
└── DesignSystemShowcase.tsx
|
|
```
|
|
|
|
## Route Guard Components
|
|
|
|
### ProtectedRoute
|
|
|
|
Requires authentication and optionally onboarding.
|
|
|
|
```typescript
|
|
interface ProtectedRouteProps {
|
|
requireOnboarded?: boolean;
|
|
}
|
|
|
|
// Usage in AppRoutes.tsx
|
|
<Route element={<ProtectedRoute />}>
|
|
<Route path="/onboarding/*" element={<Onboarding />} />
|
|
</Route>
|
|
|
|
<Route element={<ProtectedRoute requireOnboarded />}>
|
|
<Route path="/home" element={<Home />} />
|
|
</Route>
|
|
```
|
|
|
|
### PublicRoute
|
|
|
|
Redirects authenticated users away.
|
|
|
|
```typescript
|
|
// Usage in AppRoutes.tsx
|
|
<Route element={<PublicRoute />}>
|
|
<Route path="/" element={<Welcome />} />
|
|
<Route path="/login" element={<Login />} />
|
|
</Route>
|
|
```
|
|
|
|
### DefaultRedirect
|
|
|
|
Fallback that routes based on auth state.
|
|
|
|
```typescript
|
|
// Redirects to:
|
|
// - "/" if not authenticated
|
|
// - "/onboarding" if authenticated but not onboarded
|
|
// - "/home" if authenticated and onboarded
|
|
```
|
|
|
|
## Authentication Components
|
|
|
|
### TelegramLoginButton
|
|
|
|
OAuth login button for Telegram.
|
|
|
|
```typescript
|
|
interface TelegramLoginButtonProps {
|
|
onClick: () => void;
|
|
disabled?: boolean;
|
|
}
|
|
|
|
// Usage
|
|
<TelegramLoginButton
|
|
onClick={() => openUrl(`${BACKEND_URL}/auth/telegram?platform=desktop`)}
|
|
/>
|
|
```
|
|
|
|
## Connection Status Components
|
|
|
|
### ConnectionIndicator
|
|
|
|
Generic connection status badge.
|
|
|
|
```typescript
|
|
interface ConnectionIndicatorProps {
|
|
status: 'connected' | 'connecting' | 'disconnected' | 'error';
|
|
label?: string;
|
|
}
|
|
|
|
<ConnectionIndicator status="connected" label="Socket" />
|
|
```
|
|
|
|
### TelegramConnectionIndicator
|
|
|
|
Telegram-specific status display.
|
|
|
|
```typescript
|
|
interface TelegramConnectionIndicatorProps {
|
|
status: 'connected' | 'connecting' | 'disconnected' | 'error';
|
|
}
|
|
|
|
// Usage with Redux state
|
|
const telegramStatus = useAppSelector((state) =>
|
|
selectTelegramConnectionStatus(state, userId)
|
|
);
|
|
|
|
<TelegramConnectionIndicator status={telegramStatus} />
|
|
```
|
|
|
|
### TelegramConnectionModal
|
|
|
|
Modal for setting up Telegram connection.
|
|
|
|
```typescript
|
|
interface TelegramConnectionModalProps {
|
|
isOpen: boolean;
|
|
onClose: () => void;
|
|
}
|
|
|
|
// Usage in onboarding/settings
|
|
const [showModal, setShowModal] = useState(false);
|
|
|
|
<TelegramConnectionModal
|
|
isOpen={showModal}
|
|
onClose={() => setShowModal(false)}
|
|
/>
|
|
```
|
|
|
|
**Features:**
|
|
|
|
- QR code login flow
|
|
- Phone number login flow
|
|
- Connection status display
|
|
- Error handling
|
|
|
|
### GmailConnectionIndicator
|
|
|
|
Gmail status badge (future integration).
|
|
|
|
```typescript
|
|
<GmailConnectionIndicator status="coming-soon" />
|
|
```
|
|
|
|
## Onboarding Components
|
|
|
|
### ProgressIndicator
|
|
|
|
Visual progress through onboarding steps.
|
|
|
|
```typescript
|
|
interface ProgressIndicatorProps {
|
|
current: number;
|
|
total: number;
|
|
}
|
|
|
|
<ProgressIndicator current={2} total={5} />
|
|
```
|
|
|
|
### LottieAnimation
|
|
|
|
Lottie animation player for onboarding.
|
|
|
|
```typescript
|
|
interface LottieAnimationProps {
|
|
animationData: object;
|
|
loop?: boolean;
|
|
autoplay?: boolean;
|
|
className?: string;
|
|
}
|
|
|
|
import welcomeAnimation from '../assets/animations/welcome.json';
|
|
|
|
<LottieAnimation
|
|
animationData={welcomeAnimation}
|
|
loop={true}
|
|
autoplay={true}
|
|
/>
|
|
```
|
|
|
|
## Settings Modal System
|
|
|
|
Complete modal system with URL-based routing.
|
|
|
|
### File Structure
|
|
|
|
```
|
|
components/settings/
|
|
├── SettingsModal.tsx # Route-based container
|
|
├── SettingsLayout.tsx # Portal + backdrop wrapper
|
|
├── SettingsHome.tsx # Main menu with profile
|
|
├── panels/
|
|
│ ├── ConnectionsPanel.tsx # Connection management
|
|
│ ├── MessagingPanel.tsx # (Future)
|
|
│ ├── PrivacyPanel.tsx # (Future)
|
|
│ ├── ProfilePanel.tsx # (Future)
|
|
│ ├── AdvancedPanel.tsx # (Future)
|
|
│ └── BillingPanel.tsx # (Future)
|
|
├── components/
|
|
│ ├── SettingsHeader.tsx # User profile section
|
|
│ ├── SettingsMenuItem.tsx # Menu item component
|
|
│ ├── SettingsBackButton.tsx # Back navigation
|
|
│ └── SettingsPanelLayout.tsx# Panel wrapper
|
|
└── hooks/
|
|
├── useSettingsNavigation.ts # URL routing
|
|
└── useSettingsAnimation.ts # Animation state
|
|
```
|
|
|
|
### SettingsModal
|
|
|
|
Main container that renders based on URL.
|
|
|
|
```typescript
|
|
export function SettingsModal() {
|
|
const location = useLocation();
|
|
const isOpen = location.pathname.startsWith('/settings');
|
|
|
|
if (!isOpen) return null;
|
|
|
|
return (
|
|
<SettingsLayout>
|
|
{/* Route to appropriate panel */}
|
|
{location.pathname === '/settings' && <SettingsHome />}
|
|
{location.pathname === '/settings/connections' && <ConnectionsPanel />}
|
|
{/* ... more panels */}
|
|
</SettingsLayout>
|
|
);
|
|
}
|
|
```
|
|
|
|
### SettingsLayout
|
|
|
|
Portal-based modal wrapper.
|
|
|
|
```typescript
|
|
export function SettingsLayout({ children }) {
|
|
const { closeModal } = useSettingsNavigation();
|
|
|
|
return createPortal(
|
|
<div className="fixed inset-0 z-50">
|
|
{/* Backdrop */}
|
|
<div
|
|
className="absolute inset-0 bg-black/50 backdrop-blur-sm"
|
|
onClick={closeModal}
|
|
/>
|
|
|
|
{/* Modal */}
|
|
<div className="absolute inset-4 flex items-center justify-center">
|
|
<div className="bg-white rounded-2xl w-full max-w-[520px] shadow-xl">
|
|
{children}
|
|
</div>
|
|
</div>
|
|
</div>,
|
|
document.body
|
|
);
|
|
}
|
|
```
|
|
|
|
### SettingsHome
|
|
|
|
Main menu with user profile.
|
|
|
|
```typescript
|
|
export function SettingsHome() {
|
|
const { navigateTo, closeModal } = useSettingsNavigation();
|
|
const user = useAppSelector((state) => state.user.profile);
|
|
|
|
const menuItems = [
|
|
{ id: 'connections', label: 'Connections', icon: LinkIcon },
|
|
{ id: 'messaging', label: 'Messaging', icon: MessageIcon },
|
|
{ id: 'privacy', label: 'Privacy', icon: ShieldIcon },
|
|
// ... more items
|
|
];
|
|
|
|
return (
|
|
<div>
|
|
<SettingsHeader user={user} onClose={closeModal} />
|
|
|
|
{menuItems.map((item) => (
|
|
<SettingsMenuItem
|
|
key={item.id}
|
|
{...item}
|
|
onClick={() => navigateTo(item.id)}
|
|
/>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|
|
```
|
|
|
|
### ConnectionsPanel
|
|
|
|
Connection management interface.
|
|
|
|
```typescript
|
|
export function ConnectionsPanel() {
|
|
const { navigateBack } = useSettingsNavigation();
|
|
const [telegramModalOpen, setTelegramModalOpen] = useState(false);
|
|
|
|
const telegramStatus = useAppSelector((state) =>
|
|
selectTelegramConnectionStatus(state, userId)
|
|
);
|
|
|
|
// Reuses connectOptions from onboarding
|
|
const connections = connectOptions.map((opt) => ({
|
|
...opt,
|
|
status: opt.id === 'telegram' ? telegramStatus : 'coming-soon'
|
|
}));
|
|
|
|
return (
|
|
<SettingsPanelLayout title="Connections" onBack={navigateBack}>
|
|
{connections.map((conn) => (
|
|
<ConnectionItem
|
|
key={conn.id}
|
|
{...conn}
|
|
onConnect={() => conn.id === 'telegram' && setTelegramModalOpen(true)}
|
|
/>
|
|
))}
|
|
|
|
<TelegramConnectionModal
|
|
isOpen={telegramModalOpen}
|
|
onClose={() => setTelegramModalOpen(false)}
|
|
/>
|
|
</SettingsPanelLayout>
|
|
);
|
|
}
|
|
```
|
|
|
|
### Settings Hooks
|
|
|
|
#### useSettingsNavigation
|
|
|
|
URL-based navigation for settings modal.
|
|
|
|
```typescript
|
|
interface UseSettingsNavigationReturn {
|
|
currentRoute: string;
|
|
navigateTo: (panel: string) => void;
|
|
navigateBack: () => void;
|
|
closeModal: () => void;
|
|
}
|
|
|
|
const { navigateTo, navigateBack, closeModal } = useSettingsNavigation();
|
|
|
|
// Navigate to panel
|
|
navigateTo('connections'); // → /settings/connections
|
|
|
|
// Go back
|
|
navigateBack(); // → /settings
|
|
|
|
// Close modal
|
|
closeModal(); // → previous non-settings route
|
|
```
|
|
|
|
#### useSettingsAnimation
|
|
|
|
Animation state management.
|
|
|
|
```typescript
|
|
interface UseSettingsAnimationReturn {
|
|
isEntering: boolean;
|
|
isExiting: boolean;
|
|
animationClass: string;
|
|
}
|
|
|
|
const { animationClass } = useSettingsAnimation();
|
|
|
|
<div className={`modal ${animationClass}`}>
|
|
{/* Content */}
|
|
</div>
|
|
```
|
|
|
|
### Settings Components
|
|
|
|
#### SettingsHeader
|
|
|
|
User profile section at top of settings.
|
|
|
|
```typescript
|
|
interface SettingsHeaderProps {
|
|
user: User | null;
|
|
onClose: () => void;
|
|
}
|
|
|
|
<SettingsHeader user={user} onClose={handleClose} />
|
|
```
|
|
|
|
#### SettingsMenuItem
|
|
|
|
Individual menu item with icon and chevron.
|
|
|
|
```typescript
|
|
interface SettingsMenuItemProps {
|
|
label: string;
|
|
icon: React.ComponentType;
|
|
onClick: () => void;
|
|
badge?: string;
|
|
disabled?: boolean;
|
|
}
|
|
|
|
<SettingsMenuItem
|
|
label="Connections"
|
|
icon={LinkIcon}
|
|
onClick={() => navigateTo('connections')}
|
|
badge="2"
|
|
/>
|
|
```
|
|
|
|
#### SettingsBackButton
|
|
|
|
Back navigation button.
|
|
|
|
```typescript
|
|
interface SettingsBackButtonProps {
|
|
onClick: () => void;
|
|
}
|
|
|
|
<SettingsBackButton onClick={navigateBack} />
|
|
```
|
|
|
|
#### SettingsPanelLayout
|
|
|
|
Wrapper for settings panels.
|
|
|
|
```typescript
|
|
interface SettingsPanelLayoutProps {
|
|
title: string;
|
|
onBack: () => void;
|
|
children: React.ReactNode;
|
|
}
|
|
|
|
<SettingsPanelLayout title="Connections" onBack={navigateBack}>
|
|
{/* Panel content */}
|
|
</SettingsPanelLayout>
|
|
```
|
|
|
|
## Component Patterns
|
|
|
|
### Reusing Connection Options
|
|
|
|
The `connectOptions` array is shared between onboarding and settings:
|
|
|
|
```typescript
|
|
// Defined in ConnectStep.tsx, imported elsewhere
|
|
export const connectOptions = [
|
|
{
|
|
id: 'telegram',
|
|
label: 'Telegram',
|
|
icon: TelegramIcon,
|
|
description: 'Connect your Telegram account',
|
|
},
|
|
{
|
|
id: 'gmail',
|
|
label: 'Gmail',
|
|
icon: GmailIcon,
|
|
description: 'Connect your Gmail account',
|
|
comingSoon: true,
|
|
},
|
|
];
|
|
```
|
|
|
|
### Modal via Portal
|
|
|
|
Settings modal uses `createPortal` to render outside the component tree:
|
|
|
|
```typescript
|
|
return createPortal(
|
|
<div className="modal-container">
|
|
{/* Modal content */}
|
|
</div>,
|
|
document.body
|
|
);
|
|
```
|
|
|
|
### Controlled vs Uncontrolled
|
|
|
|
Connection modals are controlled components:
|
|
|
|
```typescript
|
|
// Parent controls open state
|
|
const [isOpen, setIsOpen] = useState(false);
|
|
|
|
<TelegramConnectionModal
|
|
isOpen={isOpen}
|
|
onClose={() => setIsOpen(false)}
|
|
/>
|
|
```
|
|
|
|
---
|
|
|
|
_Previous: [Pages & Routing](./05-pages-routing.md) | Next: [Providers](./07-providers.md)_
|