diff --git a/api/src/user.ts b/api/src/user.ts index c98583c..0a198e6 100644 --- a/api/src/user.ts +++ b/api/src/user.ts @@ -5,6 +5,7 @@ import { StreamChat } from "stream-chat"; import type { Transporter } from "nodemailer"; import { generateToken } from "./token.js"; import { config } from "./config.js"; +import type { Tables } from "./database.types.js"; export const userRouter = new Hono<{ Variables: { @@ -44,12 +45,14 @@ userRouter.post("/invite", async (c) => { const token = generateToken(); - const { data: tablo, error: tabloError } = await supabase + const { data, error: tabloError } = await supabase .from("tablos") .select("*") .eq("id", tablo_id) .single(); + const tablo = data as Tables<"tablos">; + if (tabloError) { return c.json({ error: tabloError.message }, 500); } @@ -80,10 +83,53 @@ userRouter.post("/invite", async (c) => { from: `${sender.email} via XTablo `, to: recipientmail, subject: "Vous avez été invité à un tablo", - html: `

Vous avez été invité à un tablo avec ce lien

`, + html: `

Vous avez été invité à un tablo avec ce lien

`, }); return c.json({ message: "Invite sent successfully", }); }); + +userRouter.post("/join-tablo", async (c) => { + const { token } = await c.req.json(); + + const joiner = c.get("user"); + const supabase = c.get("supabase"); + + const { data, error } = await supabase + .from("tablo_invites") + .select("id, tablo_id, invited_by") + .eq("invite_token", token) + .eq("invited_email", joiner.email) + .single(); + + if (error) { + return c.json({ error: error.message }, 500); + } + + if (!data) { + return c.json({ error: "Invalid token or email" }, 400); + } + + const { id: invite_id, tablo_id, invited_by } = data; + + const { error: tabloAccessError } = await supabase + .from("tablo_access") + .insert({ + tablo_id, + user_id: joiner.id, + // ** IMPORTANT ** + is_admin: false, + // ------------- + is_active: true, + granted_by: invited_by, + }); + + if (tabloAccessError) { + return c.json({ error: tabloAccessError.message }, 500); + } + + await supabase.from("tablo_invites").delete().eq("id", invite_id); + return c.json({ message: "Tablo joined successfully" }); +}); diff --git a/ui/src/hooks/invite.ts b/ui/src/hooks/invite.ts index 2e52efe..c4c5f7b 100644 --- a/ui/src/hooks/invite.ts +++ b/ui/src/hooks/invite.ts @@ -30,3 +30,22 @@ export const useInviteUser = () => { }); return mutate; }; + +export const useJoinTablo = () => { + const { session } = useSession(); + const { mutate } = useMutation({ + mutationFn: async ({ token }: { token: string }) => { + const { data } = await api.post( + "/api/v1/users/join-tablo", + { token }, + { + headers: { + Authorization: `Bearer ${session?.access_token}`, + }, + } + ); + return data; + }, + }); + return mutate; +}; diff --git a/ui/src/pages/join.tsx b/ui/src/pages/join.tsx index 646c4a0..f2d23e6 100644 --- a/ui/src/pages/join.tsx +++ b/ui/src/pages/join.tsx @@ -1,13 +1,16 @@ -import { useParams, useNavigate } from "react-router-dom"; +import { useParams, useNavigate, useSearchParams } from "react-router-dom"; import { useUser } from "@ui/providers/UserStoreProvider"; +import { useJoinTablo } from "@ui/hooks/invite"; export const JoinPage = () => { const { tablo_name } = useParams<{ tablo_name: string }>(); // const [searchParams] = useSearchParams(); const navigate = useNavigate(); const user = useUser(); + const joinTablo = useJoinTablo(); - // const token = searchParams.get("token"); + const [searchParams] = useSearchParams(); + const token = searchParams.get("token"); // const handleJoinTablo = async () => { // if (!user || !tablo_name || !token) return; @@ -59,38 +62,40 @@ export const JoinPage = () => { // ); // } - if (!user) { - return ( -
-
-

- Rejoindre Tablo -

-
-

{tablo_name}

-

- Vous avez été invité(e) à rejoindre ce tablo -

-
-

- Veuillez vous connecter pour accepter cette invitation -

- -
-
- ); - } + // if (!user) { + // return ( + //
+ //
+ //

+ // Rejoindre Tablo "{tablo_name}" + //

+ //
+ //

{tablo_name}

+ //

+ // Vous avez été invité(e) à rejoindre ce tablo + //

+ //
+ //

+ // Veuillez vous connecter pour accepter cette invitation + //

+ // + //
+ //
+ // ); + // } return (
-

Rejoindre Tablo

+

+ Rejoindre Tablo "{tablo_name}" +

@@ -99,13 +104,26 @@ export const JoinPage = () => { {tablo_name}

- Vous avez été invité(e) à rejoindre ce tablo + Vous avez été invité(e) par un enculé à rejoindre ce tablo