AgentSkillsCN

lacajita-frontend

La Cajita TV 前端开发的技能。适用于处理 React、TypeScript、Tailwind CSS、UI 组件、页面、前端服务,或位于 /fastapi-playlists/Lacajita/Adm-Caj/src/ 中的任何文件时使用。

SKILL.md
--- frontmatter
name: lacajita-frontend
description: Skill para desarrollo del frontend de La Cajita TV. Usar cuando se trabaje con React, TypeScript, Tailwind CSS, componentes UI, páginas, servicios del frontend, o cualquier archivo en /fastapi-playlists/Lacajita/Adm-Caj/src/.
license: MIT

La Cajita TV - Frontend Skill

Guía para desarrollo del frontend React + TypeScript + Tailwind CSS v4.

Stack Tecnológico

  • React 19.0.0 con TypeScript 5.7.2
  • Vite 6.3.5 como bundler
  • Tailwind CSS v4 (migrado desde Bootstrap)
  • React Router 7.x para navegación
  • Auth0 React SDK 2.x para autenticación

Estructura del Proyecto

code
/opt/adm-caja-unified/fastapi-playlists/Lacajita/Adm-Caj/
├── src/
│   ├── components/
│   │   ├── ui/          # ⚠️ COMPONENTES AUTORIZADOS
│   │   ├── common/      # Componentes compartidos
│   │   └── Header/      # Componentes específicos
│   ├── pages/           # Páginas/vistas
│   ├── services/        # Servicios API
│   ├── context/         # React Context
│   ├── hooks/           # Custom hooks
│   └── types/           # TypeScript types
├── dist/                # Build de producción
└── vite.config.ts

⚠️ Regla Crítica: Componentes UI

SIEMPRE importar componentes desde /src/components/ui/:

typescript
// ✅ CORRECTO
import { Button, Card, Modal, Alert, Badge } from '@/components/ui';
import { Form, Table, Spinner, Tabs } from '../../components/ui';

// ❌ PROHIBIDO
import Button from '../ui/button/Button';
import { Modal } from 'react-bootstrap';

Componentes Disponibles

ComponenteProps principales
Buttonvariant: 'primary' | 'secondary' | 'danger' | 'outline'
Card, CardHeader, CardBodyclassName, children
Alertvariant: 'info' | 'success' | 'warning' | 'danger'
Modalshow, onClose, title, size
Badgevariant, children
Form.Group, Form.Label, Form.Control-
Tablestriped, hover, responsive
Spinnersize, variant
Tabs, TabactiveKey, onSelect

Patrones de Código

Componente Funcional con Tipos

typescript
interface VideoCardProps {
  video: Video;
  onSelect?: (id: string) => void;
}

const VideoCard: React.FC<VideoCardProps> = ({ video, onSelect }) => {
  return (
    <Card>
      <CardBody>
        <h3>{video.title}</h3>
        <Button variant="primary" onClick={() => onSelect?.(video.id)}>
          Ver
        </Button>
      </CardBody>
    </Card>
  );
};

Servicio API

typescript
// src/services/videoService.ts
import { getApiUrl, getAuthHeaders } from './api';

export const fetchVideos = async (token: string): Promise<Video[]> => {
  const response = await fetch(`${getApiUrl()}/videos`, {
    headers: getAuthHeaders(token)
  });
  if (!response.ok) throw new Error('Error fetching videos');
  return response.json();
};

Custom Hook

typescript
// src/hooks/useVideos.ts
export const useVideos = () => {
  const { getAccessTokenSilently } = useAuth0();
  const [videos, setVideos] = useState<Video[]>([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const load = async () => {
      try {
        const token = await getAccessTokenSilently();
        const data = await fetchVideos(token);
        setVideos(data);
      } finally {
        setLoading(false);
      }
    };
    load();
  }, []);

  return { videos, loading };
};

Comandos

bash
cd /opt/adm-caja-unified/fastapi-playlists/Lacajita/Adm-Caj

# Desarrollo
npm run dev          # Inicia Vite + backend

# Build producción
npm run build        # Genera /dist

# Lint
npm run lint

Configuración Auth0

Variables en .env:

code
VITE_AUTH0_DOMAIN=lacajita.us.auth0.com
VITE_AUTH0_CLIENT_ID=...
VITE_AUTH0_AUDIENCE=https://api.lacajita.tv
VITE_API_URL=https://caja.segrd.com/api

Checklist Pre-Commit

  • Componentes UI importados desde @/components/ui
  • Tipos TypeScript definidos (sin any)
  • npm run build exitoso
  • Sin errores de lint