Expert guidance for building a Mini Jira Clone frontend with React 19+, TypeScript, Zustand, Ant Design, and Tailwind CSS. Covers component architecture, state management, routing, and performance optimization.
Expert guidance for building a production-ready Mini Jira Clone frontend using modern React patterns and best practices.
**Functional Component Patterns:**
**Example Component:**
```typescript
interface TaskFormProps {
task?: Task;
onSubmit: (data: TaskFormData) => Promise<void>;
onCancel: () => void;
}
function TaskForm({ task, onSubmit, onCancel }: TaskFormProps) {
const [form] = Form.useForm();
const [isLoading, setIsLoading] = useState(false);
const handleSubmit = useCallback(
async (values: TaskFormData) => {
setIsLoading(true);
try {
await onSubmit(values);
} finally {
setIsLoading(false);
}
},
[onSubmit]
);
return (
<Form form={form} onFinish={handleSubmit} layout="vertical">
{/* Form fields */}
</Form>
);
}
export default React.memo(TaskForm);
```
**Route Structure:**
**Protected Routes:**
**Store Organization:**
Create domain-separated stores:
**authStore:**
```typescript
interface AuthStore {
user: User | null;
isAuthenticated: boolean;
login: (credentials: LoginData) => Promise<void>;
logout: () => void;
refreshUser: () => Promise<void>;
}
```
**taskStore:**
```typescript
interface TaskStore {
tasks: Task[];
filters: TaskFilters;
fetchTasks: () => Promise<void>;
createTask: (data: TaskFormData) => Promise<void>;
updateTask: (id: string, data: Partial<Task>) => Promise<void>;
deleteTask: (id: string) => Promise<void>;
setFilters: (filters: TaskFilters) => void;
}
```
**uiStore:**
```typescript
interface UIStore {
isTaskModalOpen: boolean;
isLoading: boolean;
notifications: Notification[];
openTaskModal: () => void;
closeTaskModal: () => void;
showNotification: (message: string, type: NotificationType) => void;
}
```
**Best Practices:**
**Ant Design Components:**
Use Antd for complex UI:
**Tailwind CSS:**
**Responsive Design:**
**Code Splitting:**
```typescript
const DashboardPage = React.lazy(() => import('./pages/DashboardPage'));
function App() {
return (
<Suspense fallback={<LoadingSpinner />}>
<Routes>
<Route path="/dashboard" element={<DashboardPage />} />
</Routes>
</Suspense>
);
}
```
**Memoization:**
**Bundle Optimization:**
```
src/
├── components/
│ ├── common/ # Layout, Header, Footer
│ ├── features/
│ │ ├── auth/ # Login, Register components
│ │ ├── tasks/ # Task list, form, card
│ │ └── projects/ # Project components
│ └── ui/ # Custom UI primitives
├── pages/
│ ├── LoginPage.tsx
│ ├── RegisterPage.tsx
│ └── DashboardPage.tsx
├── stores/
│ ├── authStore.ts
│ ├── taskStore.ts
│ └── uiStore.ts
├── assets/ # Images, icons
├── routes/ # Route configuration
├── hooks/ # Custom hooks
├── types/ # TypeScript definitions
├── services/ # API services
├── apis/ # API abstractions
├── utils/ # Utility functions
├── constants/ # App constants
└── styles/ # Global styles
```
**HTTP Client Setup:**
**Example Service:**
```typescript
import axios from 'axios';
const api = axios.create({
baseURL: import.meta.env.VITE_API_URL,
});
api.interceptors.request.use((config) => {
const token = getAuthToken();
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
api.interceptors.response.use(
(response) => response,
(error) => {
if (error.response?.status === 401) {
// Handle unauthorized
}
return Promise.reject(error);
}
);
```
**Authentication Flow:**
**Error Boundaries:**
```typescript
class ErrorBoundary extends React.Component<Props, State> {
static getDerivedStateFromError(error: Error) {
return { hasError: true, error };
}
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
console.error('Error caught:', error, errorInfo);
}
render() {
if (this.state.hasError) {
return <ErrorFallback error={this.state.error} />;
}
return this.props.children;
}
}
```
**Form Validation:**
**Input Validation:**
**Authentication Security:**
**Development Tools:**
**Environment Management:**
```
VITE_API_URL=https://api.example.com
VITE_APP_ENV=production
```
**Creating a Task List Component:**
```typescript
function TaskList() {
const { tasks, fetchTasks } = useTaskStore();
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
const loadTasks = async () => {
setIsLoading(true);
try {
await fetchTasks();
} finally {
setIsLoading(false);
}
};
loadTasks();
}, [fetchTasks]);
return (
<List
loading={isLoading}
dataSource={tasks}
renderItem={(task) => <TaskCard task={task} />}
/>
);
}
```
**Protected Route Pattern:**
```typescript
function ProtectedRoute({ children }: { children: React.ReactNode }) {
const { isAuthenticated } = useAuthStore();
if (!isAuthenticated) {
return <Navigate to="/login" replace />;
}
return <>{children}</>;
}
```
Generate all code following these principles for production-ready quality with proper typing, error handling, and accessibility.
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/senior-react-developer-mini-jira-frontend/raw