diff --git a/src/components/sva/inputNumber.ts b/src/components/sva/inputNumber.ts new file mode 100644 index 0000000..5f1d2f1 --- /dev/null +++ b/src/components/sva/inputNumber.ts @@ -0,0 +1,61 @@ +import { numberInputAnatomy } from "@ark-ui/react"; +import { sva } from "panda/css"; + +/** + * Ark UI の [Popover コンポーネント](https://ark-ui.com/react/docs/components/popover) の基底スタイル + * + * 書き方 refs: + * - https://panda-css.com/docs/concepts/slot-recipes + * - https://ark-ui.com/react/docs/guides/styling#styling-with-panda-css + * - https://speakerdeck.com/ikumatadokoro/panda-css-to-ark-ui-dehazimeruge-ren-kai-fa?slide=31 + */ +export const svaNumberInput = sva({ + className: "NumberInput", + slots: numberInputAnatomy.keys(), + base: { + root: { + width: "100%", + margin: "auto", + borderRadius: "md", + padding: "1rem", + border: "1px solid", + borderColor: "wkb-neutral.900", + position: "relative", + }, + label: { + fontSize: "sm", + fontWeight: "bold", + position: "absolute", + top: "-1.5rem", + }, + input: { + color: "wkb-neutral.900", + rounded: "md", + shadow: "md", + width: "100%", + p: "1rem", + textAlign: "left", + }, + incrementTrigger: { + bg: "wkb-neutral.900", + rounded: "md", + shadow: "md", + }, + decrementTrigger: { + bg: "wkb-neutral.900", + rounded: "md", + shadow: "md", + }, + control: { + display: "flex", + flexDirection: "column", + position: "absolute", + right: "0", + top: "0", + bottom: "0", + justifyContent: "space-between", + bg: "wkb-neutral.100", + color: "wkb-neutral.900", + }, + }, +}); diff --git a/src/lib/classes/user.ts b/src/lib/classes/user.ts index 18e33f7..f60178b 100644 --- a/src/lib/classes/user.ts +++ b/src/lib/classes/user.ts @@ -36,9 +36,11 @@ export class User { static async signIn(): Promise { match( - await supabase.auth.signInWithPassword({ - email: "user01@example.com", - password: "password", + await supabase.auth.signInWithOAuth({ + provider: "google", + options: { + redirectTo: `${document.location.origin}/user/auth`, + }, }), ).with(S.Error, ({ error }) => { notifyErrorInToast("User.signIn", error, "サインインに失敗しました"); diff --git a/src/routes/user/index.tsx b/src/routes/user/index.tsx index c58c11c..eab5e0b 100644 --- a/src/routes/user/index.tsx +++ b/src/routes/user/index.tsx @@ -1,16 +1,18 @@ +import { Field, NumberInput } from "@ark-ui/react"; import { Icon } from "@iconify/react"; -import { type Session } from "@supabase/supabase-js"; import { createFileRoute } from "@tanstack/react-router"; import { useSetAtom } from "jotai"; -import { styled as p, VStack } from "panda/jsx"; -import { type ReactElement } from "react"; +import { Grid, styled as p, VStack } from "panda/jsx"; +import { useState, type ReactElement } from "react"; import { z } from "zod"; import { IconText } from "@/components/IconText"; import { Button } from "@/components/cva/Button"; import { Expanded } from "@/components/cva/Expanded"; -import { useSession } from "@/hooks/useSession"; +import { svaNumberInput } from "@/components/sva/numberInput"; +import { svaTextArea } from "@/components/sva/textArea"; import { User } from "@/lib/classes/user"; import { $redirectTo } from "@/lib/stores/redirect"; +import { notifyTableErrorInToast } from "@/lib/utils/table"; export const Route = createFileRoute("/user/")({ validateSearch: (s) => @@ -20,24 +22,183 @@ export const Route = createFileRoute("/user/")({ }) .parse(s), component: () => { - const { session } = useSession(); + const { session } = Route.useRouteContext(); + + if (session == null) return ; + const user = new User(session); return session != null ? ( - + ) : ( ); }, }); -function Authenticated({ session }: { session: Session }): ReactElement { - const { metadata } = new User(session); +function Authenticated({ user }: { user: User }): ReactElement { + const [selected, setSelected] = useState<"sower" | "sponsor" | null>(); + const [age, setAge] = useState(0); + const [description, setDescription] = useState(""); + const numberInput = svaNumberInput(); + const textArea = svaTextArea(); return ( - - ログインしました! - {metadata.name} + + {selected == null && ( + <> + + アカウントタイプを選択して下さい + + + + + + + )} + {selected === "sower" && ( + <> + 年齢を入力して下さい + + + { + setAge(Number(e.target.value)); + }} + /> + + { + setAge((prev) => prev + 1); + }} + > + + + { + setAge((prev) => prev - 1); + }} + > + + + + + + + + )} + {selected === "sponsor" && ( + <> + 企業の説明を入力して下さい + + { + setDescription(e.target.value); + }} + value={description} + /> + + + + )} ); @@ -54,7 +215,7 @@ function NotAuthenticated(): ReactElement { まずはログインしてみましょう!