t3-stack入門 (4) T3-appにTodo作成機能を追加する

今までのところTodo一覧、Todo削除しかないので、Todo作成機能を作ってみます
## Todo作成Mutationをtrpcに追加
```diff_typescript
@@ -3,6 +3,13 @@ import { z } from "zod";
 import { router, publicProcedure } from "../trpc";
 
 export const todoRouter = router({
+  create: publicProcedure
+    .input(z.object({ title: z.string(), description: z.string() }))
+    .mutation(({ input, ctx }) => {
+      return ctx.prisma.todo.create({
+        data: input,
+      });
+    }),
   delete: publicProcedure

```
## Todo画面にTodo作成フォームを追加する
Todo画面にTodo作成フォームを追加します。Mantine-formを使うとフォームを簡単に追加することができて便利です。

```diff_typescript
@@ -1,13 +1,29 @@
-import { ActionIcon, Card, Group, Text } from "@mantine/core";
+import {
+  ActionIcon,
+  Card,
+  Group,
+  Text,
+  TextInput,
+  Textarea,
+  Button,
+} from "@mantine/core";
 import { type NextPage } from "next";
 import { Trash } from "tabler-icons-react";
 import { Layout } from "../components/Layout";
+            label="Title"
+            placeholder="Title"
+            {...form.getInputProps("title")}
+          />
+          <Textarea
+            label="Description"
+            placeholder="Description"
+            {...form.getInputProps("description")}
+          />
+          <Button type="submit" mt="sm">
+            New Task
+          </Button>
+        </form>
         {todos.data?.map((todo) => (
           <Card withBorder key={todo.id} mt={"sm"}>
             <Group position={"apart"}>
```


## Todo作成フォームにバリデーション機能を追加
今のままだと、何も入っていないTodoを作成できてしまいます。バリデーション機能を追加したいと思います。
trpcもMantine-formも入力のバリデーションでzodを使うことができますので、zodのSchemaを共有したいと思います。
src/server/trpc/router/todo.tsxでcreateTodoSchemaをExport、src/pages/todos.tsxでcreateTodoSchemaを利用するように変更
してみたのですが、
```
Uncaught Error: You're trying to use @trpc/server in a non-server environment. This is not supported by default.
```
と言われてしまいました。どうやらsrc/serverにあるファイルはクライアント側からは見えないようです。考えてみたら当たり前でした。
src/schema/todo.tsxを作成します。
```typescript
import { z } from "zod";

export const createTodoSchema = z.object({
  title: z.string().min(3, { message: "Must be 3 or more characters long" }),
  description: z
    .string()
    .min(5, { message: "Must be 5 or more characters long" }),
});
```
src/server/trpc/router/todo.tsx,src/pages/todo.tsxでcreateTodoSchemaを利用するように変更します

```diff_typescript
@@ -1,8 +1,14 @@
 import { z } from "zod";
+import { createTodoSchema } from "../../../schema/todo";
 
 import { router, publicProcedure } from "../trpc";
 
 export const todoRouter = router({
-  create: publicProcedure
-    .input(z.object({ title: z.string(), description: z.string() }))
-    .mutation(({ input, ctx }) => {
-      return ctx.prisma.todo.create({
-        data: input,
-      });
-    }),
+  create: publicProcedure.input(createTodoSchema).mutation(({ input, ctx }) => {
+    return ctx.prisma.todo.create({
+      data: input,
+    });
+  }),
   delete: publicProcedure
```

```diff_typescript
 import { Layout } from "../components/Layout";
-import { useForm } from "@mantine/form";
+import { useForm, zodResolver } from "@mantine/form";
 import { trpc } from "../utils/trpc";
+import { createTodoSchema } from "../schema/todo";
 
 const Todo: NextPage = () => {
   const utils = trpc.useContext();
   const form = useForm({
     initialValues: { title: "", description: "" },
+    validate: zodResolver(createTodoSchema),
   });
```
画面を開いて、何も入っていない段階で"New Task"を押してみます。
![new_todo_error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508186/69fc29e8-5923-f560-e9e9-68bc356c3aee.png)


ちゃんとエラーが表示されました。

## ButtonのBackgroundが透明になる問題
tailwind,mantineを使うと、ボタンの背景色が透明になってしまいます。
https://stackoverflow.com/questions/72083381/load-mantine-styles-after-tailwind-preflight
こちらを見ると、tailwindのpreflightをfalseにすると書いてありますのでtailwind.config.cjsを変更します。
```diff_javascript
  plugins: [],
+  corePlugins: {
+    preflight: false,
+  },
};

```
![button_bg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508186/9421508e-2d4f-fbb7-7a86-dcbf3277973e.png)


ボタンの背景色が設定どおりの色になりました。

ここまでの変更内容は以下の通りです。

https://github.com/bioflowy/t3-todo-example/commit/c9de945907265a598d75f7429158c8e06c5f2fe3