From 3866262fc3e23ede7cd4abcda6521f06c8cf6562 Mon Sep 17 00:00:00 2001
From: Arthur Belleville
Date: Fri, 24 Oct 2025 17:56:45 +0200
Subject: [PATCH] Join tablo forwards to the details
---
api/src/tablo.ts | 79 +++++++++++++++++++++--------------
apps/main/src/hooks/invite.ts | 2 +-
apps/main/src/pages/join.tsx | 7 ++--
apps/main/stats.html | 2 +-
4 files changed, 54 insertions(+), 36 deletions(-)
diff --git a/api/src/tablo.ts b/api/src/tablo.ts
index bb5488e..fd39cd4 100644
--- a/api/src/tablo.ts
+++ b/api/src/tablo.ts
@@ -6,7 +6,11 @@ import type { StreamChat } from "stream-chat";
import { config } from "./config.js";
import type { Tables } from "./database.types.ts";
import { writeCalendarFileToR2 } from "./helpers.js";
-import { authMiddleware, r2Middleware, streamChatMiddleware } from "./middleware.js";
+import {
+ authMiddleware,
+ r2Middleware,
+ streamChatMiddleware,
+} from "./middleware.js";
import { generateToken } from "./token.js";
import { transporter } from "./transporter.js";
import type { EventInsertInTablo, TabloInsert } from "./types.ts";
@@ -166,7 +170,9 @@ tabloRouter.post("/create-and-invite", async (c) => {
const { data: insertedTablo, error } = await supabase
.from("tablos")
.insert({
- name: `${invitedUserDataTyped.name || "Invité"} / ${ownerDataTyped.name || "Propriétaire"}`,
+ name: `${invitedUserDataTyped.name || "Invité"} / ${
+ ownerDataTyped.name || "Propriétaire"
+ }`,
color: "bg-blue-500",
status: "todo",
owner_id: ownerId,
@@ -184,20 +190,22 @@ tabloRouter.post("/create-and-invite", async (c) => {
}
// Grant access to the current user (invited user) as a non-admin member
- const { error: tabloAccessError } = await supabase.from("tablo_access").insert(
- {
- tablo_id: tabloData.id,
- user_id: user.id,
- // ** IMPORTANT **
- is_admin: false,
- // -------------
- is_active: true,
- granted_by: ownerId,
- }
- // {
- // onConflict: "tablo_id, user_id",
- // }
- );
+ const { error: tabloAccessError } = await supabase
+ .from("tablo_access")
+ .insert(
+ {
+ tablo_id: tabloData.id,
+ user_id: user.id,
+ // ** IMPORTANT **
+ is_admin: false,
+ // -------------
+ is_active: true,
+ granted_by: ownerId,
+ }
+ // {
+ // onConflict: "tablo_id, user_id",
+ // }
+ );
if (tabloAccessError) {
console.error("tabloAccessError", tabloAccessError);
@@ -290,7 +298,8 @@ tabloRouter.patch("/update", async (c) => {
const updatedTablo = update as Tables<"tablos">;
- const isUpdatingName = tablo.name !== undefined && tablo.name !== updatedTablo.name;
+ const isUpdatingName =
+ tablo.name !== undefined && tablo.name !== updatedTablo.name;
if (error) {
return c.json({ error: error.message }, 500);
@@ -335,7 +344,10 @@ tabloRouter.delete("/delete", async (c) => {
.single();
if (accessError || !tabloAccess || !tabloAccess.is_admin) {
- return c.json({ error: "You are not authorized to delete this tablo" }, 403);
+ return c.json(
+ { error: "You are not authorized to delete this tablo" },
+ 403
+ );
}
if (error) {
@@ -376,7 +388,10 @@ tabloRouter.post("/invite", async (c) => {
}
if (tablo.owner_id !== sender.id) {
- return c.json({ error: "You are not allowed to invite users to this tablo" }, 400);
+ return c.json(
+ { error: "You are not allowed to invite users to this tablo" },
+ 400
+ );
}
const { data: introConfigData, error: introError } = await supabase
@@ -410,8 +425,8 @@ tabloRouter.post("/invite", async (c) => {
Cliquez sur ce lien pour accepter l'invitation.
+ token
+ )}">ce lien pour accepter l'invitation.
Cordialement.
`,
@@ -447,15 +462,17 @@ tabloRouter.post("/join", async (c) => {
const { id: invite_id, tablo_id, invited_by } = inviteData;
- 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,
- });
+ 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) {
console.error("tabloAccessError", tabloAccessError);
@@ -471,7 +488,7 @@ tabloRouter.post("/join", async (c) => {
console.error("error adding member to channel", error);
}
- return c.json({ message: "Tablo joined successfully" });
+ return c.json({ tablo_id });
});
tabloRouter.get("/members/:tablo_id", async (c) => {
diff --git a/apps/main/src/hooks/invite.ts b/apps/main/src/hooks/invite.ts
index 8d3a7ce..f7244fd 100644
--- a/apps/main/src/hooks/invite.ts
+++ b/apps/main/src/hooks/invite.ts
@@ -31,7 +31,7 @@ export const useInviteUser = () => {
export const useJoinTablo = () => {
const api = useAuthedApi();
- const { mutate } = useMutation({
+ const { mutate } = useMutation<{ tablo_id: string }, unknown, { token: string }>({
mutationFn: async ({ token }: { token: string }) => {
const { data } = await api.post("/api/v1/tablos/join", { token });
return data;
diff --git a/apps/main/src/pages/join.tsx b/apps/main/src/pages/join.tsx
index 49ceea0..425b0a8 100644
--- a/apps/main/src/pages/join.tsx
+++ b/apps/main/src/pages/join.tsx
@@ -53,14 +53,15 @@ export const JoinPage = () => {
joinTablo(
{ token },
{
- onSuccess: () => {
- navigate("/");
+ onSuccess: ({ tablo_id }) => {
+ navigate(`/tablos/${tablo_id}`);
},
onError: (error) => {
+ console.error(error);
toast.add(
{
title: "Erreur",
- description: error.message,
+ description: "Une erreur est survenue.",
type: "error",
},
{ timeout: 2000 }
diff --git a/apps/main/stats.html b/apps/main/stats.html
index 5a67cd6..43ddb46 100644
--- a/apps/main/stats.html
+++ b/apps/main/stats.html
@@ -4929,7 +4929,7 @@ var drawChart = (function (exports) {