Use JSON seed data for snippets

This commit is contained in:
2026-01-17 23:53:46 +00:00
parent 381697e2a3
commit 497ccaa10f
3 changed files with 38 additions and 358 deletions

View File

@@ -45,7 +45,20 @@
"category": "Components",
"hasPreview": true,
"functionName": "AnimatedCard",
"inputParameters": [],
"inputParameters": [
{
"name": "title",
"type": "string",
"defaultValue": "Animated Card",
"description": "Card title"
},
{
"name": "description",
"type": "string",
"defaultValue": "Hover to see the effect",
"description": "Card description"
}
],
"createdAt": 0,
"updatedAt": 0
},
@@ -62,4 +75,4 @@
"createdAt": 0,
"updatedAt": 0
}
]
]

View File

@@ -19,7 +19,20 @@
"category": "Templates",
"hasPreview": true,
"functionName": "Greeting",
"inputParameters": []
"inputParameters": [
{
"name": "name",
"type": "string",
"defaultValue": "World",
"description": "Name to greet"
},
{
"name": "message",
"type": "string",
"defaultValue": "Hello",
"description": "Greeting message"
}
]
},
{
"id": "template-3",
@@ -32,4 +45,4 @@
"functionName": "StatefulComponent",
"inputParameters": []
}
]
]

View File

@@ -220,366 +220,20 @@ export async function seedDatabase(): Promise<void> {
const now = Date.now()
const seedSnippets: Snippet[] = [
{
id: 'seed-1',
title: 'React Counter Hook',
description: 'Basic state management with useState',
code: `import { useState } from 'react'
function Counter() {
const [count, setCount] = useState(0)
return (
<div className="p-6 space-y-4">
<p className="text-2xl font-bold">Count: {count}</p>
<div className="flex gap-2">
<button
onClick={() => setCount(count + 1)}
className="px-4 py-2 bg-primary text-primary-foreground rounded"
>
Increment
</button>
<button
onClick={() => setCount(count - 1)}
className="px-4 py-2 bg-secondary text-secondary-foreground rounded"
>
Decrement
</button>
</div>
</div>
)
}
export default Counter`,
language: 'tsx',
category: 'React Hooks',
hasPreview: true,
functionName: 'Counter',
inputParameters: [],
createdAt: now,
updatedAt: now
},
{
id: 'seed-2',
title: 'Todo List Component',
description: 'Complete todo list with add, toggle, and delete',
code: `import { useState } from 'react'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Card } from '@/components/ui/card'
import { Checkbox } from '@/components/ui/checkbox'
import { Trash2 } from '@phosphor-icons/react'
function TodoList() {
const [todos, setTodos] = useState([
{ id: 1, text: 'Learn React', completed: false },
{ id: 2, text: 'Build a project', completed: false }
])
const [input, setInput] = useState('')
const addTodo = () => {
if (input.trim()) {
setTodos([...todos, { id: Date.now(), text: input, completed: false }])
setInput('')
const seedSnippets: Snippet[] = seedSnippetsData.map((snippet, index) => {
const timestamp = now - index * 1000
return {
...snippet,
createdAt: timestamp,
updatedAt: timestamp
}
}
const toggleTodo = (id) => {
setTodos(todos.map(todo =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo
))
}
const deleteTodo = (id) => {
setTodos(todos.filter(todo => todo.id !== id))
}
return (
<Card className="p-6 max-w-md mx-auto">
<h2 className="text-2xl font-bold mb-4">My Todos</h2>
<div className="flex gap-2 mb-4">
<Input
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && addTodo()}
placeholder="Add a new todo..."
/>
<Button onClick={addTodo}>Add</Button>
</div>
<div className="space-y-2">
{todos.map(todo => (
<div key={todo.id} className="flex items-center gap-2 p-2 hover:bg-muted rounded">
<Checkbox
checked={todo.completed}
onCheckedChange={() => toggleTodo(todo.id)}
/>
<span className={todo.completed ? 'line-through text-muted-foreground flex-1' : 'flex-1'}>
{todo.text}
</span>
<Button
variant="ghost"
size="icon"
onClick={() => deleteTodo(todo.id)}
>
<Trash2 size={16} />
</Button>
</div>
))}
</div>
</Card>
)
}
export default TodoList`,
language: 'tsx',
category: 'Components',
hasPreview: true,
functionName: 'TodoList',
inputParameters: [],
createdAt: now - 1000,
updatedAt: now - 1000
},
{
id: 'seed-3',
title: 'Fetch Data Hook',
description: 'Custom hook for API data fetching',
code: `import { useState, useEffect } from 'react'
function useFetch(url) {
const [data, setData] = useState(null)
const [loading, setLoading] = useState(true)
const [error, setError] = useState(null)
useEffect(() => {
const fetchData = async () => {
try {
setLoading(true)
const response = await fetch(url)
if (!response.ok) throw new Error('Network response was not ok')
const json = await response.json()
setData(json)
setError(null)
} catch (err) {
setError(err.message)
} finally {
setLoading(false)
}
}
fetchData()
}, [url])
return { data, loading, error }
}`,
language: 'tsx',
category: 'React Hooks',
hasPreview: false,
createdAt: now - 2000,
updatedAt: now - 2000
},
{
id: 'seed-4',
title: 'Animated Card',
description: 'Card with hover animation using Framer Motion',
code: `import { motion } from 'framer-motion'
import { Card, CardHeader, CardTitle, CardDescription, CardContent } from '@/components/ui/card'
function AnimatedCard({ title = 'Animated Card', description = 'Hover to see the effect' }) {
return (
<motion.div
whileHover={{ scale: 1.05, rotateZ: 2 }}
whileTap={{ scale: 0.95 }}
transition={{ type: 'spring', stiffness: 300, damping: 20 }}
>
<Card className="cursor-pointer">
<CardHeader>
<CardTitle>{title}</CardTitle>
<CardDescription>{description}</CardDescription>
</CardHeader>
<CardContent>
<p>This card has smooth animations on hover and tap!</p>
</CardContent>
</Card>
</motion.div>
)
}
export default AnimatedCard`,
language: 'tsx',
category: 'Components',
hasPreview: true,
functionName: 'AnimatedCard',
inputParameters: [
{
name: 'title',
type: 'string',
defaultValue: 'Animated Card',
description: 'Card title'
},
{
name: 'description',
type: 'string',
defaultValue: 'Hover to see the effect',
description: 'Card description'
}
],
createdAt: now - 3000,
updatedAt: now - 3000
},
{
id: 'seed-5',
title: 'Form Validation',
description: 'Form with react-hook-form validation',
code: `import { useForm } from 'react-hook-form'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Card } from '@/components/ui/card'
function ContactForm() {
const { register, handleSubmit, formState: { errors } } = useForm()
const onSubmit = (data) => {
console.log('Form data:', data)
alert('Form submitted successfully!')
}
return (
<Card className="p-6 max-w-md mx-auto">
<h2 className="text-2xl font-bold mb-4">Contact Form</h2>
<form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
<div>
<Label htmlFor="name">Name</Label>
<Input
id="name"
{...register('name', { required: 'Name is required' })}
/>
{errors.name && (
<p className="text-destructive text-sm mt-1">{errors.name.message}</p>
)}
</div>
<div>
<Label htmlFor="email">Email</Label>
<Input
id="email"
type="email"
{...register('email', {
required: 'Email is required',
pattern: {
value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}$/i,
message: 'Invalid email address'
}
})}
/>
{errors.email && (
<p className="text-destructive text-sm mt-1">{errors.email.message}</p>
)}
</div>
<Button type="submit" className="w-full">Submit</Button>
</form>
</Card>
)
}
export default ContactForm`,
language: 'tsx',
category: 'Forms',
hasPreview: true,
functionName: 'ContactForm',
inputParameters: [],
createdAt: now - 4000,
updatedAt: now - 4000
}
]
})
for (const snippet of seedSnippets) {
await createSnippet(snippet)
}
const seedTemplates: SnippetTemplate[] = [
{
id: 'template-1',
title: 'Basic React Component',
description: 'Simple functional component template',
code: `function MyComponent() {
return (
<div className="p-4">
<h2 className="text-xl font-bold">Hello World</h2>
<p>This is a basic component.</p>
</div>
)
}
export default MyComponent`,
language: 'tsx',
category: 'Templates',
hasPreview: true,
functionName: 'MyComponent',
inputParameters: []
},
{
id: 'template-2',
title: 'Component with Props',
description: 'Component template with configurable props',
code: `function Greeting({ name = 'World', message = 'Hello' }) {
return (
<div className="p-4">
<h2 className="text-xl font-bold">{message}, {name}!</h2>
</div>
)
}
export default Greeting`,
language: 'tsx',
category: 'Templates',
hasPreview: true,
functionName: 'Greeting',
inputParameters: [
{
name: 'name',
type: 'string',
defaultValue: 'World',
description: 'Name to greet'
},
{
name: 'message',
type: 'string',
defaultValue: 'Hello',
description: 'Greeting message'
}
]
},
{
id: 'template-3',
title: 'useState Hook Template',
description: 'Component with state management',
code: `import { useState } from 'react'
import { Button } from '@/components/ui/button'
function StatefulComponent() {
const [value, setValue] = useState(0)
return (
<div className="p-4 space-y-4">
<p className="text-lg">Value: {value}</p>
<Button onClick={() => setValue(value + 1)}>
Increment
</Button>
</div>
)
}
export default StatefulComponent`,
language: 'tsx',
category: 'Templates',
hasPreview: true,
functionName: 'StatefulComponent',
inputParameters: []
}
]
const seedTemplates: SnippetTemplate[] = seedTemplatesData
for (const template of seedTemplates) {
await createTemplate(template)