今までのところTodo一覧、Todo削除しかないので、Todo作成機能を作ってみます
Todo作成Mutationをtrpcに追加
@@ -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を使うとフォームを簡単に追加することができて便利です。
@@ -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を作成します。
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を利用するように変更します
@@ -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
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"を押してみます。
ちゃんとエラーが表示されました。
ButtonのBackgroundが透明になる問題
tailwind,mantineを使うと、ボタンの背景色が透明になってしまいます。
https://stackoverflow.com/questions/72083381/load-mantine-styles-after-tailwind-preflight
こちらを見ると、tailwindのpreflightをfalseにすると書いてありますのでtailwind.config.cjsを変更します。
plugins: [],
+ corePlugins: {
+ preflight: false,
+ },
};
ボタンの背景色が設定どおりの色になりました。
ここまでの変更内容は以下の通りです。