Adding New Components
Relevant source files
The following files were used as context for generating this wiki page:This document outlines the process and architecture for creating and integrating new React components into the AI for Thai EMS application. The project uses a modular, component-based structure with React, TypeScript, and Tailwind CSS, which allows for consistent and maintainable UI development.
The core of the application is the App.tsx component, which serves as the main container, assembling various smaller, reusable components to construct the user interface. These individual components are located in the components/ directory. Understanding this structure is key to extending the application with new features and UI elements.
Sources: App.tsx, components/Section.tsx, index.tsx:3-4
Component Architecture
The application's front-end architecture is built around composing functional React components. The main App component renders the page layout by importing and arranging child components.
Sources: App.tsx:2-11, 14-114
Component Hierarchy
The following diagram illustrates how the main App component composes various child components to build the application's UI.
This diagram shows that index.tsx renders the main App component. App.tsx then imports and uses several other components like Header, Section, and AiDemo to build the page. Components like Card are used within Section, and Icons.tsx provides SVG icons to multiple components.
Sources: App.tsx:2-11, index.tsx:4, 13
Key Files and Directories
| File / Directory | Description |
|---|---|
App.tsx | The main application component that assembles all other UI components. |
index.tsx | The entry point of the React application, which renders App.tsx into the DOM. |
components/ | Directory containing all reusable React components. |
components/Icons.tsx | A collection of SVG icons exported as React components for use throughout the app. |
constants.ts | Stores static data arrays and objects (e.g., projectObjectives, researchTeam) used by components. |
types.ts | Contains TypeScript interface definitions for data structures used across the application. |
index.html | The main HTML file that includes the root div for the React app and the Tailwind CSS configuration. |
Sources: App.tsx, index.tsx, components/Icons.tsx, constants.ts, types.ts, index.html
Creating a New Component
Follow these steps to create a new, reusable component. We will use the example of creating a simple, self-contained component.
1. Component File Creation
All components are defined within the components/ directory. Create a new file with a .tsx extension (e.g., MyNewComponent.tsx).
2. Basic Component Structure
A component is a TypeScript-flavored React Functional Component (React.FC). It should accept props for customization. The Card.tsx component is a good, simple example to follow.
// In components/MyNewComponent.tsx
import React from 'react';
// 1. Define the props interface
interface MyNewComponentProps {
title: string;
children: React.ReactNode;
}
// 2. Create the functional component
export const MyNewComponent: React.FC<MyNewComponentProps> = ({ title, children }) => {
return (
// 3. Use Tailwind CSS for styling
<div className="bg-white p-4 rounded-lg shadow-md">
<h3 className="text-xl font-bold text-brand-primary mb-2">{title}</h3>
<div>{children}</div>
</div>
);
};
Sources: components/Card.tsx:3-15, components/Section.tsx:3-17
3. Styling and Icons
Styling is handled exclusively via Tailwind CSS. The project defines custom colors in index.html which should be used for consistency.
- Custom Colors:
niem-blue,niem-yellow,brand-primary,brand-secondary. - Icons: To use an icon, import it from
components/Icons.tsxand render it as a component.
import { BeakerIcon } from './Icons'; // Import the desired icon
// Inside your component's return statement
<div className="flex items-start space-x-4">
<div className="flex-shrink-0 w-12 h-12 bg-yellow-100 text-brand-secondary rounded-full flex items-center justify-center">
<BeakerIcon className="w-6 h-6" />
</div>
{/* ... other content */}
</div>
Sources: index.html:15-19, App.tsx:89-92, components/Icons.tsx
4. Integration into the Application
Once the component is created, import it into a parent component (usually App.tsx or another container component) and use it in the JSX.
// In App.tsx
// 1. Import the new component
import { MyNewComponent } from './components/MyNewComponent';
import { Header } from './components/Header';
// ... other imports
const App: React.FC = () => {
return (
<div className="min-h-screen">
<Header />
<main>
{/* 2. Use the new component with props */}
<MyNewComponent title="This is a New Section">
<p>Content for the new component.</p>
</MyNewComponent>
{/* ... other components */}
</main>
</div>
);
};
Sources: App.tsx:2-11, 14-114
Handling State and Data
Components can be stateless, receive data via props, or manage their own internal state.
Static Data from Constants
For static content that doesn't change, define it in constants.ts and import it into your component. App.tsx does this to render the project objectives and research team.
// In App.tsx
import { projectObjectives } from './constants';
import { Card } from './components/Card';
// ... inside the App component
<Section title="วัตถุประสงค์โครงการ">
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-6">
{projectObjectives.map((obj, index) => (
<Card key={index} title={`(${index + 1}) ${obj.title}`}>
<p>{obj.description}</p>
</Card>
))}
</div>
</Section>
Sources: App.tsx:7, 39-45, constants.ts:3-20
Dynamic State with Hooks
For interactive components, use React hooks like useState and useEffect to manage state. The AiDemo and Chatbot components are excellent reference examples.
The AiDemo component manages the simulation's state (idle, running, finished), the conversation transcript, and the analysis results from the AI.
The following flowchart shows the state transitions in the AiDemo component.
The Chatbot component uses state to manage its visibility (isOpen), the message history (messages), loading status (isLoading), and user input. It interacts with geminiService to stream responses from the AI.
This sequence diagram shows the flow of sending a message in the chatbot.
Summary
Adding a new component to this project is a straightforward process designed for modularity. By following the established patterns—creating a new React.FC file in the components directory, using Tailwind CSS for styling, managing state with hooks, and integrating it into App.tsx—developers can efficiently extend the application's UI while maintaining code quality and consistency.
Sources: App.tsx, components/Section.tsx, components/AiDemo.tsx