FR

frontend-architecture

Design patterns and architectural standards for SeShop frontend.

Install

mkdir -p .claude/skills/frontend-architecture-dieuxuanhien && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/15196" && unzip -o skill.zip -d .claude/skills/frontend-architecture-dieuxuanhien && rm skill.zip

Installs to .claude/skills/frontend-architecture-dieuxuanhien

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Frontend architecture and design patterns for SeShop. Use when: understanding React component structure, designing state management, integrating APIs, or querying view specifications.
183 chars✓ has a “when” trigger
Intermediate

Key capabilities

  • Understand React component structure and hierarchy
  • Design state management patterns using Redux Toolkit or Context API
  • Integrate backend APIs with Axios and interceptors
  • Implement role-based UI routing with React Router v6
  • Optimize component performance through code splitting and memoization
  • Handle errors with custom error messages and types

How it works

The skill provides structured knowledge on SeShop's frontend architecture, covering component design, state management, API integration, routing, and performance optimization using React, TypeScript, and Vite.

Inputs & outputs

You give it
Request for frontend architecture guidance or implementation details for SeShop
You get back
Architectural knowledge, design patterns, or code examples for SeShop frontend

When to use frontend-architecture

  • Understanding component composition
  • Implementing new API integrations
  • Designing UI routes

About this skill

SeShop Frontend Architecture Skill

This skill provides architectural knowledge for SeShop frontend implementation using React, TypeScript, and Vite.

When to Use

  • Understanding component hierarchy and composition
  • Designing state management patterns
  • Integrating backend APIs with proper error handling
  • Implementing role-based UI routing
  • Optimizing component performance

Architecture Overview

Framework: React 18+ with TypeScript
Build Tool: Vite
State Management: Redux Toolkit or Context API
HTTP Client: Axios with interceptors
Routing: React Router v6

Directory Structure

src/
├── pages/ → Top-level pages (route destinations)
│   ├── Admin/
│   │   ├── Dashboard.tsx → ADMIN_001
│   │   ├── UserManagement.tsx → ADMIN_002
│   │   ├── LocationsManagement.tsx → ADMIN_003
│   │   └── ...
│   ├── Staff/
│   │   ├── CatalogManagement.tsx → STAFF_001
│   │   ├── InventoryAdjustment.tsx → STAFF_002
│   │   └── ...
│   └── Customer/
│       ├── Browse.tsx → CUST_001
│       ├── ProductDetail.tsx → CUST_002
│       └── ...
│
├── components/ → Reusable components
│   ├── common/
│   │   ├── Header.tsx
│   │   ├── Sidebar.tsx
│   │   ├── Footer.tsx
│   │   └── ErrorBoundary.tsx
│   ├── forms/
│   │   ├── LoginForm.tsx
│   │   ├── ProductForm.tsx
│   │   └── CheckoutForm.tsx
│   ├── tables/
│   │   ├── ProductsTable.tsx
│   │   ├── OrdersTable.tsx
│   │   └── InventoryTable.tsx
│   └── widgets/
│       ├── StockWidget.tsx
│       ├── PriceDisplay.tsx
│       └── AIRecommendationChat.tsx
│
├── hooks/ → Custom React hooks
│   ├── useAuth.ts → Auth state and methods
│   ├── useApi.ts → API calls with loading/error
│   ├── useLocalStorage.ts → Persist state
│   └── useDebounce.ts → Debounce values
│
├── store/ → Redux slices (if using Redux)
│   ├── authSlice.ts → User, permissions, token
│   ├── cartSlice.ts → Cart items, total
│   ├── orderSlice.ts → Current/recent orders
│   └── inventorySlice.ts → Stock levels
│
├── api/ → API client and endpoints
│   ├── client.ts → Axios instance with interceptors
│   ├── auth.ts → /auth/* endpoints
│   ├── products.ts → /products/* endpoints
│   ├── orders.ts → /orders/* endpoints
│   └── inventory.ts → /inventory/* endpoints
│
├── types/ → TypeScript interfaces
│   ├── models.ts → Domain models (User, Product, Order, etc.)
│   ├── api.ts → API request/response types
│   └── store.ts → Redux state types
│
├── utils/ → Helper functions
│   ├── validators.ts → Form validation
│   ├── formatters.ts → Currency, dates, etc.
│   ├── constants.ts → App constants
│   └── permissions.ts → Permission checking
│
├── styles/ → Global styles
│   ├── index.css → Global styles
│   ├── variables.css → CSS variables (colors, spacing)
│   └── breakpoints.ts → Responsive breakpoints
│
├── App.tsx → Root component with routing
└── main.tsx → Entry point

Component Design Patterns

1. Page Components (Route-Level)

// pages/Admin/Dashboard.tsx
import React, { useEffect, useState } from 'react';
import { useAuth } from '@/hooks/useAuth';
import { dashboardAPI } from '@/api/dashboard';
import { Header } from '@/components/common/Header';
import { ErrorAlert } from '@/components/common/ErrorAlert';
import { LoadingSpinner } from '@/components/common/LoadingSpinner';

export const DashboardPage: React.FC = () => {
  const { user } = useAuth();
  const [metrics, setMetrics] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    if (!user?.permissions.includes('DASHBOARD:VIEW')) {
      setError('You do not have permission to view this page');
      return;
    }

    dashboardAPI.getMetrics()
      .then(setMetrics)
      .catch(err => setError(err.message))
      .finally(() => setLoading(false));
  }, [user]);

  if (loading) return <LoadingSpinner />;
  if (error) return <ErrorAlert message={error} />;

  return (
    <>
      <Header />
      <main className="dashboard">
        {/* Dashboard content */}
      </main>
    </>
  );
};

2. Reusable Components

// components/forms/ProductForm.tsx
interface ProductFormProps {
  product?: Product;
  onSubmit: (data: ProductFormData) => Promise<void>;
  onCancel: () => void;
}

export const ProductForm: React.FC<ProductFormProps> = ({
  product,
  onSubmit,
  onCancel,
}) => {
  const [formData, setFormData] = useState<ProductFormData>(
    product ? toFormData(product) : emptyFormData
  );
  const [errors, setErrors] = useState<FormErrors>({});
  const [loading, setLoading] = useState(false);

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { name, value } = e.target;
    setFormData(prev => ({ ...prev, [name]: value }));
  };

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setErrors({});
    setLoading(true);

    try {
      const validationErrors = validateProductForm(formData);
      if (Object.keys(validationErrors).length > 0) {
        setErrors(validationErrors);
        return;
      }

      await onSubmit(formData);
    } catch (err) {
      setErrors({ submit: err.message });
    } finally {
      setLoading(false);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      {/* Form fields with error display */}
      <button type="submit" disabled={loading}>
        {loading ? 'Saving...' : 'Save'}
      </button>
      <button type="button" onClick={onCancel}>
        Cancel
      </button>
    </form>
  );
};

3. Custom Hooks for API Calls

// hooks/useApi.ts
export function useApi<T>(apiCall: () => Promise<T>) {
  const [data, setData] = useState<T | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    let isMounted = true;

    apiCall()
      .then(result => {
        if (isMounted) setData(result);
      })
      .catch(err => {
        if (isMounted) setError(err.message);
      })
      .finally(() => {
        if (isMounted) setLoading(false);
      });

    return () => {
      isMounted = false;
    };
  }, []);

  return { data, loading, error, refetch: apiCall };
}

// Usage in component
const { data: orders, loading, error } = useApi(() => 
  ordersAPI.getMyOrders()
);

4. State Management (Redux)

// store/cartSlice.ts
import { createSlice, PayloadAction } from '@reduxjs/toolkit';

interface CartItem {
  skuId: number;
  quantity: number;
  price: number;
}

interface CartState {
  items: CartItem[];
  total: number;
}

const initialState: CartState = {
  items: [],
  total: 0,
};

const cartSlice = createSlice({
  name: 'cart',
  initialState,
  reducers: {
    addItem: (state, action: PayloadAction<CartItem>) => {
      const existing = state.items.find(i => i.skuId === action.payload.skuId);
      if (existing) {
        existing.quantity += action.payload.quantity;
      } else {
        state.items.push(action.payload);
      }
      state.total = state.items.reduce(
        (sum, item) => sum + item.price * item.quantity,
        0
      );
    },
    removeItem: (state, action: PayloadAction<number>) => {
      state.items = state.items.filter(i => i.skuId !== action.payload);
      state.total = state.items.reduce(
        (sum, item) => sum + item.price * item.quantity,
        0
      );
    },
  },
});

export const { addItem, removeItem } = cartSlice.actions;
export default cartSlice.reducer;

API Integration Pattern

// api/client.ts
import axios, { AxiosInstance } from 'axios';
import { useAuth } from '@/hooks/useAuth';

export const apiClient: AxiosInstance = axios.create({
  baseURL: import.meta.env.VITE_API_URL,
  timeout: 10000,
});

// Add token to every request
apiClient.interceptors.request.use(config => {
  const token = localStorage.getItem('token');
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config;
});

// Handle errors globally
apiClient.interceptors.response.use(
  response => response.data,
  error => {
    if (error.response?.status === 401) {
      // Token expired, redirect to login
      localStorage.removeItem('token');
      window.location.href = '/login';
    }
    return Promise.reject(error.response?.data || error);
  }
);

// api/products.ts
export const productsAPI = {
  list: (params?: { page?: number; limit?: number }) =>
    apiClient.get('/products', { params }),
  
  getById: (id: number) =>
    apiClient.get(`/products/${id}`),
  
  create: (data: ProductFormData) =>
    apiClient.post('/products', data),
  
  update: (id: number, data: ProductFormData) =>
    apiClient.put(`/products/${id}`, data),
};

Routing with Role-Based Access

// App.tsx
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
import { useAuth } from '@/hooks/useAuth';
import { LoginPage } from '@/pages/LoginPage';
import { DashboardPage } from '@/pages/Admin/Dashboard';
import { Unauthorized } from '@/pages/Unauthorized';

const ProtectedRoute: React.FC<{
  component: React.ReactNode;
  requiredPermission?: string;
}> = ({ component, requiredPermission }) => {
  const { user } = useAuth();

  if (!user) {
    return <Navigate to="/login" />;
  }

  if (requiredPermission && !user.permissions.includes(requiredPermission)) {
    return <Unauthorized />;
  }

  return component;
};

export function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/login" element={<LoginPage />} />
        <Route
          path="/admin/dashboard"
          element={
            <ProtectedRoute
              component={<DashboardPage />}
              requiredPermission="DASHBOARD:VIEW"
            />
          }
        />
        {/* More routes */}
      </Routes>
    </BrowserRouter>
  );
}

Performance Optimization

1. Code Splitting by Route

const Dashboard = lazy(() => import('@/pages/A

---

*Content truncated.*

When not to use it

  • When the project is not a React 18+ application
  • When not using Vite as the build tool
  • When not using Redux Toolkit or Context API for state management

Limitations

  • Framework is React 18+ with TypeScript
  • Build Tool is Vite
  • State Management is Redux Toolkit or Context API

How it compares

This skill offers specific architectural patterns and conventions for the SeShop React application, providing tailored guidance for component organization and API handling that generic React documentation does not.

Compared to similar skills

frontend-architecture side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
frontend-architecture (this skill)03moCautionIntermediate
nextjs-best-practices316moNo flagsIntermediate
web-component-design55moNo flagsIntermediate
react-component-patterns31moNo flagsIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

Search skills

Search the agent skills registry