mirror of
https://github.com/johndoe6345789/low-code-react-app-b.git
synced 2026-04-25 22:25:01 +00:00
> spark-template@0.0.0 prebuild
> mkdir -p /tmp/dist || true
> spark-template@0.0.0 build
> tsc -b --noCheck && vite build
vite v7.3.1 building client environment for production...
<script src="/runtime-config.js"> in "/index.html" can't be bundled without type="module" attribute
✓ 37 modules transformed.
✗ Build failed in 1.07s
error during build:
[vite]: Rollup failed to resolve import "@github/spark/hooks" from "/workspaces/low-code-react-app-b/src/hooks/use-project-state.ts".
This is most likely unintended because it can break your application at runtime.
If you do want to externalize this module explicitly add it to
`build.rollupOptions.external`
at viteLog (file:///workspaces/low-code-react-app-b/node_modules/vite/dist/node/chunks/config.js:33635:57)
at file:///workspaces/low-code-react-app-b/node_modules/vite/dist/node/chunks/config.js:33669:73
at onwarn (file:///workspaces/low-code-react-app-b/node_modules/@vitejs/plugin-react-swc/index.js:76:7)
at file:///workspaces/low-code-react-app-b/node_modules/vite/dist/node/chunks/config.js:33669:28
at onRollupLog (file:///workspaces/low-code-react-app-b/node_modules/vite/dist/node/chunks/config.js:33664:63)
at onLog (file:///workspaces/low-code-react-app-b/node_modules/vite/dist/node/chunks/config.js:33467:4)
at file:///workspaces/low-code-react-app-b/node_modules/rollup/dist/es/shared/node-entry.js:20961:32
at Object.logger [as onLog] (file:///workspaces/low-code-react-app-b/node_modules/rollup/dist/es/shared/node-entry.js:22848:9)
at ModuleLoader.handleInvalidResolvedId (file:///workspaces/low-code-react-app-b/node_modules/rollup/dist/es/shared/node-entry.js:21592:26)
at file:///workspaces/low-code-react-app-b/node_modules/rollup/dist/es/shared/node-entry.js:21550:26
@johndoe6345789 ➜ /workspaces/low-code-react-app-b (main) $
146 lines
4.3 KiB
TypeScript
146 lines
4.3 KiB
TypeScript
import { useCRUD, useSearchFilter } from '@/hooks/data'
|
|
import { useToggle, useDialog } from '@/hooks/ui'
|
|
import { useKV } from '@/hooks/use-kv'
|
|
import { Button } from '@/components/ui/button'
|
|
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'
|
|
import { SearchInput, DataCard, ActionBar } from '@/components/molecules'
|
|
import { Grid, Heading, StatusBadge } from '@/components/atoms'
|
|
import { Plus, Trash, Eye } from '@phosphor-icons/react'
|
|
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'
|
|
|
|
interface Task {
|
|
id: number
|
|
title: string
|
|
status: 'active' | 'pending' | 'success'
|
|
priority: 'high' | 'medium' | 'low'
|
|
}
|
|
|
|
export function AtomicComponentDemo() {
|
|
const [tasks, setTasks] = useKV<Task[]>('demo-tasks', [
|
|
{ id: 1, title: 'Build component library', status: 'active', priority: 'high' },
|
|
{ id: 2, title: 'Write documentation', status: 'pending', priority: 'medium' },
|
|
{ id: 3, title: 'Create examples', status: 'success', priority: 'low' },
|
|
])
|
|
|
|
const crud = useCRUD<Task>({ items: tasks, setItems: setTasks })
|
|
|
|
const { searchQuery: query, setSearchQuery: setQuery, filtered } = useSearchFilter({
|
|
items: tasks,
|
|
searchFields: ['title'],
|
|
})
|
|
|
|
const showCompleted = useToggle({ initial: true })
|
|
const addDialog = useDialog()
|
|
|
|
const displayedTasks = showCompleted.value
|
|
? filtered
|
|
: filtered.filter(t => t.status !== 'success')
|
|
|
|
const handleAddTask = () => {
|
|
crud.create({
|
|
id: Date.now(),
|
|
title: 'New Task',
|
|
status: 'pending',
|
|
priority: 'medium',
|
|
})
|
|
addDialog.close()
|
|
}
|
|
|
|
const stats = {
|
|
total: tasks.length,
|
|
active: tasks.filter(t => t.status === 'active').length,
|
|
completed: tasks.filter(t => t.status === 'success').length,
|
|
}
|
|
|
|
return (
|
|
<div className="h-full overflow-auto p-6 space-y-6">
|
|
<div>
|
|
<Heading level={1} className="mb-2">
|
|
Atomic Component Demo
|
|
</Heading>
|
|
<p className="text-muted-foreground">
|
|
Demonstrating custom hooks and atomic components
|
|
</p>
|
|
</div>
|
|
|
|
<Grid cols={3} gap={4}>
|
|
<DataCard title="Total Tasks" value={stats.total} />
|
|
<DataCard title="Active" value={stats.active} />
|
|
<DataCard title="Completed" value={stats.completed} />
|
|
</Grid>
|
|
|
|
<ActionBar
|
|
title="Tasks"
|
|
actions={[
|
|
{
|
|
label: 'Add Task',
|
|
icon: <Plus size={16} />,
|
|
onClick: addDialog.open,
|
|
variant: 'default',
|
|
},
|
|
{
|
|
label: showCompleted.value ? 'Hide Completed' : 'Show Completed',
|
|
icon: <Eye size={16} />,
|
|
onClick: showCompleted.toggle,
|
|
variant: 'outline',
|
|
},
|
|
]}
|
|
/>
|
|
|
|
<SearchInput
|
|
value={query}
|
|
onChange={setQuery}
|
|
placeholder="Search tasks..."
|
|
/>
|
|
|
|
<div className="space-y-3">
|
|
{displayedTasks.map(task => (
|
|
<Card key={task.id}>
|
|
<CardHeader>
|
|
<div className="flex items-center justify-between">
|
|
<CardTitle className="text-lg">{task.title}</CardTitle>
|
|
<div className="flex items-center gap-2">
|
|
<StatusBadge status={task.status} />
|
|
<Button
|
|
variant="ghost"
|
|
size="sm"
|
|
onClick={() => crud.delete(task.id)}
|
|
>
|
|
<Trash size={16} />
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="text-sm text-muted-foreground">
|
|
Priority: {task.priority}
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
))}
|
|
</div>
|
|
|
|
{displayedTasks.length === 0 && (
|
|
<Card>
|
|
<CardContent className="py-12 text-center text-muted-foreground">
|
|
No tasks found
|
|
</CardContent>
|
|
</Card>
|
|
)}
|
|
|
|
<Dialog open={addDialog.isOpen} onOpenChange={addDialog.setOpen}>
|
|
<DialogContent>
|
|
<DialogHeader>
|
|
<DialogTitle>Add New Task</DialogTitle>
|
|
</DialogHeader>
|
|
<div className="space-y-4">
|
|
<Button onClick={handleAddTask} className="w-full">
|
|
Add Task
|
|
</Button>
|
|
</div>
|
|
</DialogContent>
|
|
</Dialog>
|
|
</div>
|
|
)
|
|
}
|