[ Home ]
back

bolt.new 生成 CMS編集、サーバー保存等 修正 shadcnUI + React

id: 176, 2024-10-15

概要:

生成AI的な、bolt.new使用して。CMS作成後、機能追加等のメモになります。

  • データ(配列データ)、サーバー保存の追加になります。

[ 公開日: 2024/10/14 ]


構成

  • bolt.new
  • shadcn/ui
  • Express.js
  • esbuild
  • typescript

関連

https://bolt.new/


作成したコード

https://github.com/kuc-arc-f/bolt_4example/tree/main/cms2


dev-start

bun run build
bun run dev


....
create: function(body: any){
  try {
    if(!body){
      throw new Error("nothing, body");
    }
console.log(body);
    const now = new Date();
    const myUUID = uuidv4();
    let row = {
      id: myUUID,
      title: body.title,
      content: body.content,
      createdAt: now.toISOString(),
    }
    this.items.push(row);
    return this.items;
  } catch (error) {
    console.error(error);
    throw new Error("error, create");
  }
},


....
return (
  <div className="container mx-auto p-4">
    <h1 className="text-3xl font-bold mb-6">CMS Article Management</h1>
    <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
      <Card>
        <CardHeader>
          <CardTitle>{editingId !== null ? "Edit Article" : "Add New Article"}</CardTitle>
        </CardHeader>
        <CardContent>
          <form onSubmit={handleSubmit} className="space-y-4">
            <Input
              type="text"
              placeholder="Article Title"
              value={title}
              onChange={(e) => setTitle(e.target.value)}
              required
            />
            <Tabs defaultValue="edit" className="w-full">
              <TabsList>
                <TabsTrigger value="edit">Edit</TabsTrigger>
                <TabsTrigger value="preview">Preview</TabsTrigger>
              </TabsList>
              <TabsContent value="edit">
                <Textarea
                  placeholder="Article Content (Markdown supported)"
                  value={content}
                  onChange={(e) => setContent(e.target.value)}
                  required
                  rows={10}
                />
              </TabsContent>
              <TabsContent value="preview">
                <div className="prose dark:prose-invert max-w-none">
                  <ReactMarkdown>{content}</ReactMarkdown>
                </div>
              </TabsContent>
            </Tabs>
            <Button type="submit">
              {editingId !== null ? "Update Article" : "Add Article"}
            </Button>
          </form>
        </CardContent>
      </Card>
      <Card>
        <CardHeader>
          <CardTitle>Article List</CardTitle>
          <div className="relative">
            <Search className="absolute left-2 top-1/2 transform -translate-y-1/2 text-gray-400" />
            <Input
              type="text"
              placeholder="Search articles..."
              value={searchTerm}
              onChange={(e) => setSearchTerm(e.target.value)}
              className="pl-8"
            />
          </div>
        </CardHeader>
        <CardContent>
          <ScrollArea className="h-[500px] pr-4">
            {filteredArticles.map(article => (
              <div key={article.id} className="mb-4 p-4 border rounded">
                <h3 className="text-xl font-semibold mb-2">{article.title}</h3>
                <div className="prose dark:prose-invert max-w-none text-sm text-gray-600 mb-2">
                  <ReactMarkdown>
                    {article.content.length > 150
                      ? `${article.content.slice(0, 150)}...`
                      : article.content}
                  </ReactMarkdown>
                </div>
                <div className="flex space-x-2">
                  <Button variant="outline" size="sm" onClick={() => handleEdit(article)}>
                    <Edit className="w-4 h-4 mr-2" /> Edit
                  </Button>
                  <Button variant="destructive" size="sm" onClick={() => {
                    if (window.confirm("Delete OK?")) {
                      handleDelete(article.id)
                    }
                  }}>
                    <Trash2 className="w-4 h-4 mr-2" /> Delete
                  </Button>
                </div>
              </div>
            ))}
          </ScrollArea>
        </CardContent>
      </Card>
    </div>
  </div>
);