--- name: frontend-core description: Build React components, pages, forms, and state management with TypeScript and TanStack Query. Use for frontend development, component creation, routing, and data fetching. --- # Frontend Core Skill ## When to Use - Creating React components or pages - Implementing forms with validation - Setting up data fetching or state management - Working with routing (/c, /o, /t) - Working with files under `frontend/` --- ## CRITICAL: Irreversible Action Confirmation (MANDATORY) ### Redeem Flow Customer screen shows "사용 처리" button → Trigger 2-step modal: **Modal Content:** - Title: "되돌릴 수 없는 작업입니다" - Body: "매장 직원이 확인 후 눌러주세요" - Buttons: [취소] (easy to hit) / [확인] **TTL Enforcement:** - If modal not confirmed within 30-60s → auto-expire - Show "요청이 만료되었습니다" → retry CTA **Why This Matters:** - Prevents accidental customer-only redemption - Forces store-side confirmation - Abuse mitigation (no auto-click scripts) --- ## Stack **Default (popular) stack:** - React + TypeScript + Vite - Tailwind CSS - React Router - TanStack Query - Axios - React Hook Form + Zod ### Libraries Policy - Use the existing stack first - Adding a new library requires: - clear benefit - small footprint - at least one example usage --- ## Architecture ### User Types & Viewports - **Customer Wallet:** mobile-first - **Owner Backoffice:** desktop-first - **Store Terminal:** always-on approval screen ### Component Composition Pattern ``` Page (route-level) └─ Container (data fetch + state) └─ View (presentational) ``` ### File Organization - `src/components/` - Common UI elements - `src/features//components/` - Feature-specific UI --- ## Code Style **Base:** Airbnb JavaScript Style Guide, with these overrides: - Indentation: 4 spaces - Max line length: 120 characters - Semicolons: false ### Naming Conventions | Type | Convention | Example | |------|------------|---------| | Components/Files | PascalCase | `UserProfile.tsx` | | Variables/Functions/Hooks | camelCase | `const isOpen = useState()` | | Constants | SCREAMING_SNAKE_CASE | `const MAX_RETRY_COUNT = 3` | **No Abbreviations:** ```typescript // bad const idx = 0 // good const index = 0 ``` **Boolean Naming:** - Use prefixes: `is`, `has`, `can`, `should` - Event handlers: `handle*` for functions, `on*` for props ```tsx // good const handleOpen = () => {}