diff --git a/app/libs/getAccountCredentials.ts b/app/libs/getAccountCredentials.ts new file mode 100644 index 0000000..5933964 --- /dev/null +++ b/app/libs/getAccountCredentials.ts @@ -0,0 +1,11 @@ +import type { SignInWithPasswordCredentials } from "@supabase/supabase-js"; + +export function getAccountCredentials( + id: string, +): SignInWithPasswordCredentials { + return { + // supabase は userId のみでサインインできないため、強引にやる + email: `email-${id}@example.com`, + password: "password", + }; +} diff --git a/app/routes/_auth._index.tsx b/app/routes/_auth._index.tsx new file mode 100644 index 0000000..02f871c --- /dev/null +++ b/app/routes/_auth._index.tsx @@ -0,0 +1,43 @@ +import type { MetaFunction } from "@remix-run/node"; +import { useSession } from "~/hooks/useSession"; + +export const meta: MetaFunction = () => { + return [ + { title: "New Remix App" }, + { name: "description", content: "Welcome to Remix!" }, + ]; +}; + +export default function Index() { + const session = useSession(); + + // 未サインインの場合 + if (!session) + return ( +
+

Game

+
+ + 匿名で登録 + +
+
+ ); + + // サインイン済みの場合 + return ( +
+

Game

+
+ Hello World +
+
+ ID: {session.user.email?.replace("@example.com", "")} +
+
+ ); +} diff --git a/app/routes/_auth.tsx b/app/routes/_auth.tsx new file mode 100644 index 0000000..996feb4 --- /dev/null +++ b/app/routes/_auth.tsx @@ -0,0 +1,17 @@ +import { Outlet, useNavigate } from "@remix-run/react"; +import { type ReactNode, useLayoutEffect } from "react"; +import { useSession } from "~/hooks/useSession"; + +// _auth.**.tsx のパスへのアクセスは必ずここで前処理される +export default function Layout(): ReactNode { + const navigate = useNavigate(); + const session = useSession(); + + useLayoutEffect(() => { + if (!session) { + navigate("/signup"); + } + }, [session, navigate]); + + return ; +} diff --git a/app/routes/_index.tsx b/app/routes/_index.tsx deleted file mode 100644 index 76d0055..0000000 --- a/app/routes/_index.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import type { MetaFunction } from "@remix-run/node"; - -export const meta: MetaFunction = () => { - return [ - { title: "New Remix App" }, - { name: "description", content: "Welcome to Remix!" }, - ]; -}; - -export default function Index() { - return ( -
-

Welcome to Remix

- -
- ); -} diff --git a/app/routes/_noauth.signin.tsx b/app/routes/_noauth.signin.tsx new file mode 100644 index 0000000..c3f8269 --- /dev/null +++ b/app/routes/_noauth.signin.tsx @@ -0,0 +1,55 @@ +import { useNavigate } from "@remix-run/react"; +import type { ReactNode } from "react"; +import { useForm } from "react-hook-form"; +import { getAccountCredentials } from "~/libs/getAccountCredentials"; +import { supabase } from "~/libs/supabase"; + +type FormValues = { + id: string; +}; + +export default function Signin(): ReactNode { + // ID でサインイン、デバッグ用(そもそもログアウトは想定していない) + const navigate = useNavigate(); + const { + register, + handleSubmit, + formState: { errors }, + } = useForm({ + mode: "onBlur", + }); + + const onSubmit = async ({ id }: FormValues) => { + const { error } = await supabase.auth.signInWithPassword( + getAccountCredentials(id), + ); + + if (error) { + console.error(error); + return; + } + + navigate("/"); + }; + + return ( +
+

Game

+

ID でサインイン

+
+ +
+ +
+ ); +} diff --git a/app/routes/_noauth.signup.tsx b/app/routes/_noauth.signup.tsx new file mode 100644 index 0000000..d43eab7 --- /dev/null +++ b/app/routes/_noauth.signup.tsx @@ -0,0 +1,34 @@ +import { useNavigate } from "@remix-run/react"; +import { v4 } from "uuid"; +import { getAccountCredentials } from "~/libs/getAccountCredentials"; +import { supabase } from "~/libs/supabase"; + +export default function Signup() { + const navigate = useNavigate(); + + const signUp = async () => { + const id = v4(); + const { error } = await supabase.auth.signUp(getAccountCredentials(id)); + + if (error) { + console.error("Error signing up:", error.message); + return; + } + + navigate("/"); + }; + return ( +
+

Game

+
+ +
+
+ ); +} diff --git a/app/routes/_noauth.tsx b/app/routes/_noauth.tsx new file mode 100644 index 0000000..24dd24a --- /dev/null +++ b/app/routes/_noauth.tsx @@ -0,0 +1,19 @@ +import { Outlet, useNavigate } from "@remix-run/react"; +import type { ReactNode } from "react"; +import { useLayoutEffect } from "react"; + +import { useSession } from "~/hooks/useSession"; + +// _noauth.**.tsx のパスへのアクセスは必ずここで前処理される +export default function Layout(): ReactNode { + const navigate = useNavigate(); + const session = useSession(); + + useLayoutEffect(() => { + if (session) { + navigate("/"); + } + }, [session, navigate]); + + return ; +}