From f0d5514421b01d7ef6de2839333e82eb6699e035 Mon Sep 17 00:00:00 2001 From: nasubi916 Date: Sat, 9 Nov 2024 22:44:29 +0900 Subject: [PATCH] ok --- src/lib/classes/user.ts | 31 ++++++++++++++++++++++++++- src/routes/user/index.tsx | 45 +++++++++++++++++++++++++++++++-------- 2 files changed, 66 insertions(+), 10 deletions(-) diff --git a/src/lib/classes/user.ts b/src/lib/classes/user.ts index f60178b..da7133f 100644 --- a/src/lib/classes/user.ts +++ b/src/lib/classes/user.ts @@ -1,6 +1,6 @@ import { type Session } from "@supabase/supabase-js"; import { type UseNavigateResult } from "@tanstack/react-router"; -import { ResultAsync } from "neverthrow"; +import { ok, ResultAsync } from "neverthrow"; import { match } from "ts-pattern"; import { Sower } from "./sower"; import { Sponsor } from "./sponsor"; @@ -107,4 +107,33 @@ export class User { Table.transformError(config, "fetchOwnComments", error), ); } + + public fetchKindOf(): TableResult< + | { + type: "SOWER"; + data: Sower; + } + | { + type: "SPONSOR"; + data: Sponsor; + } + | { + type: "UNKNOWN"; + } + > { + const data = ResultAsync.combine([ + Sower.factories.fromUser(this.id).orElse(() => ok(null)), + Sponsor.factories.fromUser(this.id).orElse(() => ok(null)), + ]); + + return data.andThen(([sower, sponsor]) => { + if (sower != null) { + return ok({ type: "SOWER", data: sower } as const); + } + if (sponsor != null) { + return ok({ type: "SPONSOR", data: sponsor } as const); + } + return ok({ type: "UNKNOWN" } as const); + }); + } } diff --git a/src/routes/user/index.tsx b/src/routes/user/index.tsx index eab5e0b..0f79770 100644 --- a/src/routes/user/index.tsx +++ b/src/routes/user/index.tsx @@ -1,9 +1,10 @@ import { Field, NumberInput } from "@ark-ui/react"; import { Icon } from "@iconify/react"; -import { createFileRoute } from "@tanstack/react-router"; +import { createFileRoute, useNavigate } from "@tanstack/react-router"; import { useSetAtom } from "jotai"; import { Grid, styled as p, VStack } from "panda/jsx"; import { useState, type ReactElement } from "react"; +import useSWRImmutable from "swr/immutable"; import { z } from "zod"; import { IconText } from "@/components/IconText"; import { Button } from "@/components/cva/Button"; @@ -13,6 +14,7 @@ import { svaTextArea } from "@/components/sva/textArea"; import { User } from "@/lib/classes/user"; import { $redirectTo } from "@/lib/stores/redirect"; import { notifyTableErrorInToast } from "@/lib/utils/table"; +import { toaster } from "@/lib/utils/toast"; export const Route = createFileRoute("/user/")({ validateSearch: (s) => @@ -36,16 +38,23 @@ export const Route = createFileRoute("/user/")({ }); function Authenticated({ user }: { user: User }): ReactElement { - const [selected, setSelected] = useState<"sower" | "sponsor" | null>(); const [age, setAge] = useState(0); + const [selected, setSelected] = useState<"sower" | "sponsor" | null>(null); const [description, setDescription] = useState(""); + const navigate = useNavigate(); const numberInput = svaNumberInput(); const textArea = svaTextArea(); + const swrUserKindOf = useSWRImmutable("userKindOf", async () => + ( + await user.fetchKindOf().mapErr(notifyTableErrorInToast("swrUserKindOf")) + )._unsafeUnwrap(), + ); + return ( - {selected == null && ( + {swrUserKindOf.data?.type === "UNKNOWN" && ( <> アカウントタイプを選択して下さい @@ -149,7 +158,15 @@ function Authenticated({ user }: { user: User }): ReactElement { name: user.metadata.name ?? "名無し", birthday: `${new Date().getFullYear() - age}-10-05T14:48:00.000Z`, }) - .mapErr(notifyTableErrorInToast("User.registerAsASower")); + .mapErr(notifyTableErrorInToast("User.registerAsASower")) + .andTee(() => { + void navigate({ to: "/" }); + }); + toaster.success({ + id: "register-as-sower", + title: "市民としてログインしました", + description: "ようこそ!", + }); }} variant="outlined" w="300px" @@ -179,11 +196,21 @@ function Authenticated({ user }: { user: User }): ReactElement {