بنقرة واحدة
scc-admin-add-page
Next.js 어드민에 새 페이지를 추가합니다. App Router, Panda CSS, React Query 패턴을 따릅니다.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Next.js 어드민에 새 페이지를 추가합니다. App Router, Panda CSS, React Query 패턴을 따릅니다.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Add new pages to SCC Admin project (Next.js 14 App Router). Use when implementing new admin pages for accessibility management, quest management, challenge management, or other features. Covers route group selection, page structure, React Query integration, form handling, navigation setup, and styling with Tailwind CSS and shadcn/ui. Use for tasks like "Add new page for X", "Create admin interface for Y", or "Implement listing/detail page for Z".
Create production-ready React UI components using shadcn/ui and Tailwind CSS. Use when creating shared components, building forms, dialogs, tables, or any UI elements. Automatically installs missing shadcn/ui components and places components in the proper directory structure (app/components/).
| name | scc-admin-add-page |
| description | Next.js 어드민에 새 페이지를 추가합니다. App Router, Panda CSS, React Query 패턴을 따릅니다. |
app/(private)/
└── {page-name}/
├── page.tsx # 메인 페이지
├── components/ # (선택) 페이지 전용 컴포넌트
└── [id]/ # (선택) 동적 라우트
└── page.tsx
'use client';
import { useQuery } from '@tanstack/react-query';
import { css } from '@/styles/css';
import { flex, stack } from '@/styles/patterns';
import { defaultApi } from '@/lib/apis/api';
export default function MyNewPage() {
const { data, isLoading, error } = useQuery({
queryKey: ['my-data'],
queryFn: () => defaultApi.getMyData(),
});
if (isLoading) return <div>로딩 중...</div>;
if (error) return <div>에러가 발생했습니다</div>;
return (
<div className={stack({ gap: '16px' })}>
<h1 className={css({ fontSize: '24px', fontWeight: 'bold' })}>
페이지 제목
</h1>
<div className={flex({ gap: '8px', wrap: 'wrap' })}>
{data?.items.map((item) => (
<ItemCard key={item.id} item={item} />
))}
</div>
</div>
);
}
'use client';
import { useForm } from 'react-hook-form';
import { useMutation } from '@tanstack/react-query';
import { css } from '@/styles/css';
import { stack } from '@/styles/patterns';
import { defaultApi } from '@/lib/apis/api';
interface FormData {
name: string;
description?: string;
}
export default function MyFormPage() {
const { register, handleSubmit, formState: { errors } } = useForm<FormData>();
const mutation = useMutation({
mutationFn: (data: FormData) => defaultApi.createItem(data),
onSuccess: () => {
alert('저장되었습니다');
},
onError: () => {
alert('에러가 발생했습니다');
},
});
return (
<form onSubmit={handleSubmit((data) => mutation.mutate(data))}>
<div className={stack({ gap: '16px' })}>
<label className={css({ display: 'flex', flexDirection: 'column', gap: '4px' })}>
이름
<input
{...register('name', { required: '이름을 입력해주세요' })}
className={css({ padding: '8px', border: '1px solid #ccc', borderRadius: '4px' })}
/>
{errors.name && <span className={css({ color: 'red' })}>{errors.name.message}</span>}
</label>
<button
type="submit"
disabled={mutation.isPending}
className={css({
padding: '12px 24px',
backgroundColor: '#007bff',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer',
_disabled: { opacity: 0.5 },
})}
>
{mutation.isPending ? '저장 중...' : '저장'}
</button>
</div>
</form>
);
}
lib/apis/api.ts에 API 호출 함수 추가:
export const getMyData = async () => {
const { data } = await defaultApi.getMyData();
return data;
};
사이드바나 헤더에 새 페이지 링크 추가 (해당하는 경우).
import { css } from '@/styles/css';
import { flex, stack, grid } from '@/styles/patterns';
// 기본 스타일
<div className={css({ padding: '16px', backgroundColor: 'white' })}>
// Flex 레이아웃
<div className={flex({ gap: '8px', align: 'center', justify: 'space-between' })}>
// Stack (수직 정렬)
<div className={stack({ gap: '16px' })}>
// Grid 레이아웃
<div className={grid({ columns: 3, gap: '16px' })}>
css({
padding: { base: '8px', md: '16px', lg: '24px' },
fontSize: { base: '14px', md: '16px' },
})
'use client' 지시문 (클라이언트 컴포넌트인 경우)(private) vs (public))css, flex, stack)@/lib/generated-sources/openapi 타입 사용useQuery, useMutation)pnpm panda # Panda CSS 생성
pnpm lint # ESLint 통과
pnpm typecheck # TypeScript 통과
CLAUDE.md - 전체 개발 가이드라인app/(private)/ 디렉토리