← スキル一覧に戻る

new-page
by abdoulayesow
Description: School management system for African schools - offline-first
⭐ 0🍴 0📅 2026年1月6日
SKILL.md
name: new-page description: Scaffold a new page with proper layout, i18n, and shadcn components. Use when creating new pages. Invoke with "/new-page [path] [description]". model: sonnet
New Page Skill
Create a new Next.js page following the project's established patterns.
Usage
/new-page admin/attendance Attendance management page
/new-page grades/reports Grade reports dashboard
/new-page students/[id]/profile Student profile page
Process
- Parse the request - Extract path and purpose
- Create page.tsx - At
app/ui/app/[path]/page.tsx - Create loading.tsx - If data fetching needed
- Add i18n keys - In both en.ts and fr.ts
- Import components - shadcn/ui components as needed
Page Template (Client Component)
"use client"
import { useState, useEffect } from "react"
import { useI18n } from "@/lib/i18n"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table"
import { Loader2 } from "lucide-react"
type DataItem = {
id: string
// Define your data shape
}
export default function PageName() {
const { t } = useI18n()
const [data, setData] = useState<DataItem[]>([])
const [loading, setLoading] = useState(true)
const [error, setError] = useState<string | null>(null)
useEffect(() => {
fetchData()
}, [])
async function fetchData() {
try {
setLoading(true)
const res = await fetch("/api/endpoint")
if (!res.ok) throw new Error("Failed to fetch")
const json = await res.json()
setData(json)
} catch (err) {
setError(err instanceof Error ? err.message : "An error occurred")
} finally {
setLoading(false)
}
}
if (loading) {
return (
<div className="flex items-center justify-center h-64">
<Loader2 className="h-8 w-8 animate-spin" />
</div>
)
}
if (error) {
return (
<div className="text-center text-red-500 p-4">
{error}
</div>
)
}
return (
<div className="container mx-auto py-6 space-y-6">
<div className="flex items-center justify-between">
<h1 className="text-2xl font-bold">{t.section.pageTitle}</h1>
<Button>{t.common.add}</Button>
</div>
<Card>
<CardHeader>
<CardTitle>{t.section.cardTitle}</CardTitle>
</CardHeader>
<CardContent>
<Table>
<TableHeader>
<TableRow>
<TableHead>{t.common.name}</TableHead>
<TableHead>{t.common.actions}</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{data.map((item) => (
<TableRow key={item.id}>
<TableCell>{item.id}</TableCell>
<TableCell>
<Button variant="ghost" size="sm">
{t.common.edit}
</Button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</CardContent>
</Card>
</div>
)
}
Loading Template
// loading.tsx
import { Skeleton } from "@/components/ui/skeleton"
import { Card, CardContent, CardHeader } from "@/components/ui/card"
export default function Loading() {
return (
<div className="container mx-auto py-6 space-y-6">
<div className="flex items-center justify-between">
<Skeleton className="h-8 w-48" />
<Skeleton className="h-10 w-24" />
</div>
<Card>
<CardHeader>
<Skeleton className="h-6 w-32" />
</CardHeader>
<CardContent className="space-y-4">
<Skeleton className="h-10 w-full" />
<Skeleton className="h-10 w-full" />
<Skeleton className="h-10 w-full" />
</CardContent>
</Card>
</div>
)
}
i18n Keys Template
// Add to en.ts
export const en = {
// ... existing keys
newSection: {
pageTitle: "Page Title",
cardTitle: "Card Title",
description: "Description text",
},
}
// Add to fr.ts
export const fr = {
// ... existing keys
newSection: {
pageTitle: "Titre de la page",
cardTitle: "Titre de la carte",
description: "Texte de description",
},
}
Checklist
Before completing:
- page.tsx created at correct path
- loading.tsx created if data fetching
- i18n keys added to en.ts
- i18n keys added to fr.ts
- shadcn/ui components imported correctly
- Loading state implemented
- Error state implemented
- TypeScript types defined
- Responsive layout (container + spacing)
Common shadcn/ui Imports
// Buttons & Actions
import { Button } from "@/components/ui/button"
// Cards
import { Card, CardContent, CardHeader, CardTitle, CardDescription, CardFooter } from "@/components/ui/card"
// Tables
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
// Forms
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
// Dialogs
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"
// Feedback
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
import { Badge } from "@/components/ui/badge"
// Icons (Lucide)
import { Loader2, Plus, Edit, Trash2, Search } from "lucide-react"
スコア
総合スコア
60/100
リポジトリの品質指標に基づく評価
✓SKILL.md
SKILL.mdファイルが含まれている
+20
✓LICENSE
ライセンスが設定されている
+10
○説明文
100文字以上の説明がある
0/10
○人気
GitHub Stars 100以上
0/15
○最近の活動
3ヶ月以内に更新がある
0/10
○フォーク
10回以上フォークされている
0/5
✓Issue管理
オープンIssueが50未満
+5
✓言語
プログラミング言語が設定されている
+5
○タグ
1つ以上のタグが設定されている
0/5
レビュー
💬
レビュー機能は近日公開予定です