mirror of
https://github.com/johndoe6345789/snippet-pastebin.git
synced 2026-04-24 13:34:55 +00:00
Merge pull request #9 from johndoe6345789/codex/convert-db-snippets.ts-to-json
Load snippet and template seed data from JSON fixtures
This commit is contained in:
@@ -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
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -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": []
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user