一键导入
frontend-patterns
Frontend development patterns for React, Next.js, state management, performance optimization, and UI best practices.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Frontend development patterns for React, Next.js, state management, performance optimization, and UI best practices.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Orquestrador Windows-first para Codex como planejador principal, Codex como executor e Codex como validador condicional, com failover reativo entre perfis Codex e handoff estruturado de baixo contexto.
Elaboração de peças jurídicas para advogados atuantes em Direito do Consumidor — petição inicial, notificação extrajudicial, recurso inominado, reclamação ao PROCON e parecer jurídico. Inclui análise do caso, enquadramento no CDC e legislação setorial, pesquisa e validação de jurisprudência exclusivamente em fontes oficiais, e entrega em dois arquivos separados: .docx da peça (pronta para uso) e .txt de validação de jurisprudência (com links oficiais para conferência manual obrigatória).
Esta skill deve ser usada quando o usuário enviar extratos bancários, planilhas de movimentação financeira, dados de PIX/TED/DOC, relatórios do BACEN, ou solicitar "analisar extrato", "verificar movimentação bancária", "incompatibilidade patrimonial", "análise financeira forense", "rastrear dinheiro", "identificar fracionamento", "quem recebeu o dinheiro", ou quando o comando /analise-bancaria for invocado. Contém metodologia completa para análise forense de dados bancários com identificação de padrões suspeitos, cálculo de incompatibilidade patrimonial e produção de laudo de análise financeira.
Esta skill deve ser usada quando o usuário pedir "analisar contradições", "confrontar depoimentos", "verificar inconsistências", "cruzar versões", "comparar o que cada um disse", "identificar mentiras", "preparar reperguntas", "qual depoimento é mais crível", ou quando o comando /contradicoes for invocado. Contém metodologia completa de análise lógica de contradições entre depoimentos, provas materiais e registros digitais, com ferramentas de classificação, avaliação de credibilidade e elaboração de roteiros de confronto para novas oitivas.
Análise completa de Relatórios de Inteligência Financeira (RIF) do COAF com geração de Relatório de Análise Financeira (RAF) em formato .docx profissional. Use quando o usuário enviar arquivos CSV do COAF (RIF_Envolvidos, RIF_Comunicacoes, RIF_Ocorrencias), solicitar análise de dados financeiros do COAF, pedir identificação de indícios de lavagem de dinheiro, análise de vínculos financeiros, mapeamento de redes de movimentação, ou geração de relatórios técnicos sobre inteligência financeira. Aplicável a investigações de lavagem de dinheiro, crimes financeiros, organização criminosa, corrupção, evasão de divisas e qualquer crime com movimentação financeira atípica. Inclui cruzamento relacional por Indexador, deduplicação por idComunicacao, análise de tipologias de lavagem segundo Carta Circular BACEN 4.001/2020 e entrega em documento Word formatado.
REST API design patterns including resource naming, status codes, pagination, filtering, error responses, versioning, and rate limiting for production APIs.
| name | frontend-patterns |
| description | Frontend development patterns for React, Next.js, state management, performance optimization, and UI best practices. |
| origin | ECC |
Modern frontend patterns for React, Next.js, and performant user interfaces.
interface CardProps {
children: React.ReactNode
variant?: 'default' | 'outlined'
}
export function Card({ children, variant = 'default' }: CardProps) {
return <div className={`card card-${variant}`}>{children}</div>
}
export function CardHeader({ children }: { children: React.ReactNode }) {
return <div className="card-header">{children}</div>
}
export function CardBody({ children }: { children: React.ReactNode }) {
return <div className="card-body">{children}</div>
}
// Usage
<Card>
<CardHeader>Title</CardHeader>
<CardBody>Content</CardBody>
</Card>
const TabsContext = createContext<TabsContextValue | undefined>(undefined)
export function Tabs({ children, defaultTab }: { children: React.ReactNode, defaultTab: string }) {
const [activeTab, setActiveTab] = useState(defaultTab)
return (
<TabsContext.Provider value={{ activeTab, setActiveTab }}>
{children}
</TabsContext.Provider>
)
}
export function Tab({ id, children }: { id: string, children: React.ReactNode }) {
const context = useContext(TabsContext)
if (!context) throw new Error('Tab must be used within Tabs')
return (
<button
className={context.activeTab === id ? 'active' : ''}
onClick={() => context.setActiveTab(id)}
>
{children}
</button>
)
}
export function useToggle(initialValue = false): [boolean, () => void] {
const [value, setValue] = useState(initialValue)
const toggle = useCallback(() => setValue(v => !v), [])
return [value, toggle]
}
const [isOpen, toggleOpen] = useToggle()
export function useQuery<T>(
key: string,
fetcher: () => Promise<T>,
options?: { onSuccess?: (data: T) => void; onError?: (error: Error) => void; enabled?: boolean }
) {
const [data, setData] = useState<T | null>(null)
const [error, setError] = useState<Error | null>(null)
const [loading, setLoading] = useState(false)
const refetch = useCallback(async () => {
setLoading(true)
setError(null)
try {
const result = await fetcher()
setData(result)
options?.onSuccess?.(result)
} catch (err) {
const error = err as Error
setError(error)
options?.onError?.(error)
} finally {
setLoading(false)
}
}, [fetcher, options])
useEffect(() => {
if (options?.enabled !== false) refetch()
}, [key, refetch, options?.enabled])
return { data, error, loading, refetch }
}
export function useDebounce<T>(value: T, delay: number): T {
const [debouncedValue, setDebouncedValue] = useState<T>(value)
useEffect(() => {
const handler = setTimeout(() => setDebouncedValue(value), delay)
return () => clearTimeout(handler)
}, [value, delay])
return debouncedValue
}
// Usage
const [searchQuery, setSearchQuery] = useState('')
const debouncedQuery = useDebounce(searchQuery, 500)
type Action =
| { type: 'SET_MARKETS'; payload: Market[] }
| { type: 'SELECT_MARKET'; payload: Market }
| { type: 'SET_LOADING'; payload: boolean }
function reducer(state: State, action: Action): State {
switch (action.type) {
case 'SET_MARKETS': return { ...state, markets: action.payload }
case 'SELECT_MARKET': return { ...state, selectedMarket: action.payload }
case 'SET_LOADING': return { ...state, loading: action.payload }
default: return state
}
}
export function MarketProvider({ children }: { children: React.ReactNode }) {
const [state, dispatch] = useReducer(reducer, {
markets: [],
selectedMarket: null,
loading: false
})
return (
<MarketContext.Provider value={{ state, dispatch }}>
{children}
</MarketContext.Provider>
)
}
// useMemo for expensive computations
const sortedMarkets = useMemo(() => {
return markets.sort((a, b) => b.volume - a.volume)
}, [markets])
// useCallback for functions passed to children
const handleSearch = useCallback((query: string) => {
setSearchQuery(query)
}, [])
// React.memo for pure components
export const MarketCard = React.memo<MarketCardProps>(({ market }) => {
return (
<div className="market-card">
<h3>{market.name}</h3>
<p>{market.description}</p>
</div>
)
})
const HeavyChart = lazy(() => import('./HeavyChart'))
export function Dashboard() {
return (
<Suspense fallback={<ChartSkeleton />}>
<HeavyChart data={data} />
</Suspense>
)
}
import { useVirtualizer } from '@tanstack/react-virtual'
export function VirtualList({ items }: { items: Item[] }) {
const parentRef = useRef<HTMLDivElement>(null)
const virtualizer = useVirtualizer({
count: items.length,
getScrollElement: () => parentRef.current,
estimateSize: () => 100,
overscan: 5
})
return (
<div ref={parentRef} style={{ height: '600px', overflow: 'auto' }}>
<div style={{ height: `${virtualizer.getTotalSize()}px`, position: 'relative' }}>
{virtualizer.getVirtualItems().map(virtualRow => (
<div
key={virtualRow.index}
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: `${virtualRow.size}px`,
transform: `translateY(${virtualRow.start}px)`
}}
>
<ItemCard item={items[virtualRow.index]} />
</div>
))}
</div>
</div>
)
}
export function CreateForm() {
const [formData, setFormData] = useState({ name: '', description: '' })
const [errors, setErrors] = useState<Record<string, string>>({})
const validate = (): boolean => {
const newErrors: Record<string, string> = {}
if (!formData.name.trim()) newErrors.name = 'Name is required'
if (!formData.description.trim()) newErrors.description = 'Description is required'
setErrors(newErrors)
return Object.keys(newErrors).length === 0
}
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
if (!validate()) return
await submitForm(formData)
}
return (
<form onSubmit={handleSubmit}>
<input
value={formData.name}
onChange={e => setFormData(prev => ({ ...prev, name: e.target.value }))}
/>
{errors.name && <span className="error">{errors.name}</span>}
<button type="submit">Submit</button>
</form>
)
}
export class ErrorBoundary extends React.Component<
{ children: React.ReactNode },
{ hasError: boolean; error: Error | null }
> {
state = { hasError: false, error: null }
static getDerivedStateFromError(error: Error) {
return { hasError: true, error }
}
render() {
if (this.state.hasError) {
return (
<div className="error-fallback">
<h2>Something went wrong</h2>
<p>{this.state.error?.message}</p>
<button onClick={() => this.setState({ hasError: false })}>
Try again
</button>
</div>
)
}
return this.props.children
}
}
import { motion, AnimatePresence } from 'framer-motion'
export function AnimatedList({ items }: { items: Item[] }) {
return (
<AnimatePresence>
{items.map(item => (
<motion.div
key={item.id}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -20 }}
transition={{ duration: 0.3 }}
>
<ItemCard item={item} />
</motion.div>
))}
</AnimatePresence>
)
}
export function Dropdown({ options, onSelect }: DropdownProps) {
const [activeIndex, setActiveIndex] = useState(0)
const handleKeyDown = (e: React.KeyboardEvent) => {
switch (e.key) {
case 'ArrowDown': e.preventDefault(); setActiveIndex(i => Math.min(i + 1, options.length - 1)); break
case 'ArrowUp': e.preventDefault(); setActiveIndex(i => Math.max(i - 1, 0)); break
case 'Enter': e.preventDefault(); onSelect(options[activeIndex]); break
case 'Escape': setIsOpen(false); break
}
}
return (
<div role="combobox" aria-expanded={isOpen} aria-haspopup="listbox" onKeyDown={handleKeyDown}>
{/* Dropdown content */}
</div>
)
}
Remember: Modern frontend patterns enable maintainable, performant user interfaces. Choose patterns that fit your project complexity.