Merge branch 'main' into develop
This commit is contained in:
commit
054bcb63ee
10 changed files with 813 additions and 763 deletions
|
|
@ -525,7 +525,9 @@ describe("Tablo Endpoint", () => {
|
|||
expect(latestNotification?.action_type).toBe("created");
|
||||
// Message is now a JSONB object with en/fr keys
|
||||
expect(latestNotification?.message).toBeDefined();
|
||||
// biome-ignore lint/suspicious/noExplicitAny: testClient requires any for dynamic route access
|
||||
expect((latestNotification?.message as any)?.en).toContain("invited");
|
||||
// biome-ignore lint/suspicious/noExplicitAny: testClient requires any for dynamic route access
|
||||
expect((latestNotification?.message as any)?.fr).toContain("invité");
|
||||
expect(latestNotification?.read_at).toBeNull();
|
||||
});
|
||||
|
|
@ -570,7 +572,9 @@ describe("Tablo Endpoint", () => {
|
|||
// Should create notification for the newly created temporary user
|
||||
expect(notificationsForInvite?.length || 0).toBeGreaterThan(0);
|
||||
// Message is now a JSONB object with en/fr keys
|
||||
// biome-ignore lint/suspicious/noExplicitAny: testClient requires any for dynamic route access
|
||||
expect((notificationsForInvite?.[0].message as any)?.en).toContain("invited");
|
||||
// biome-ignore lint/suspicious/noExplicitAny: testClient requires any for dynamic route access
|
||||
expect((notificationsForInvite?.[0].message as any)?.fr).toContain("invité");
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import { fileURLToPath } from "url";
|
|||
import { createConfig } from "./config.js";
|
||||
import { MiddlewareManager } from "./middlewares/middleware.js";
|
||||
import { getMainRouter } from "./routers/index.js";
|
||||
import { getPublicRouter } from "./routers/public.js";
|
||||
import { loadSecrets, type Secrets } from "./secrets.js";
|
||||
|
||||
tracer.init({
|
||||
|
|
@ -55,7 +54,6 @@ async function startServer(secrets: Secrets) {
|
|||
});
|
||||
|
||||
app.route("/api/v1", getMainRouter(config));
|
||||
app.route("/api/public", getPublicRouter());
|
||||
|
||||
serve(
|
||||
{
|
||||
|
|
|
|||
|
|
@ -16,9 +16,6 @@ export const getMainRouter = (config: AppConfig) => {
|
|||
// Apply supabase middleware globally (needed by all routes)
|
||||
mainRouter.use(middlewareManager.supabase);
|
||||
|
||||
// public routes (only need supabase, no other middlewares)
|
||||
mainRouter.route("/public", getPublicRouter());
|
||||
|
||||
// Apply remaining middlewares after public routes
|
||||
mainRouter.use(middlewareManager.streamChat);
|
||||
mainRouter.use(middlewareManager.r2);
|
||||
|
|
@ -26,6 +23,9 @@ export const getMainRouter = (config: AppConfig) => {
|
|||
mainRouter.use(middlewareManager.stripe);
|
||||
mainRouter.use(middlewareManager.stripeSync);
|
||||
|
||||
// public routes
|
||||
mainRouter.route("/public", getPublicRouter());
|
||||
|
||||
// tasks routes
|
||||
mainRouter.route("/tasks", getTaskRouter());
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ import {
|
|||
} from "../helpers/slots.js";
|
||||
import type { BaseEnv } from "../types/app.types.js";
|
||||
|
||||
// import { MiddlewareManager } from "../middlewares/middleware.js";
|
||||
|
||||
const factory = createFactory<BaseEnv>();
|
||||
|
||||
const getPublicSlots = factory.createHandlers(async (c) => {
|
||||
|
|
@ -124,7 +126,8 @@ const getPublicSlots = factory.createHandlers(async (c) => {
|
|||
});
|
||||
|
||||
export const getPublicRouter = () => {
|
||||
const publicRouter = new Hono();
|
||||
const publicRouter = new Hono<BaseEnv>();
|
||||
|
||||
publicRouter.get("/slots/:shortUserId/:standardName", ...getPublicSlots);
|
||||
|
||||
return publicRouter;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import type { Database } from "@xtablo/shared-types";
|
||||
import { Badge } from "@xtablo/ui/components/badge";
|
||||
import { Button } from "@xtablo/ui/components/button";
|
||||
import {
|
||||
|
|
@ -13,21 +14,20 @@ import {
|
|||
} from "@xtablo/ui/components/typography";
|
||||
import {
|
||||
BellIcon,
|
||||
CheckCheckIcon,
|
||||
CalendarIcon,
|
||||
CheckCheckIcon,
|
||||
FileTextIcon,
|
||||
KanbanIcon,
|
||||
LayoutDashboardIcon,
|
||||
UserPlusIcon,
|
||||
MailIcon,
|
||||
UserPlusIcon,
|
||||
XIcon,
|
||||
} from "lucide-react";
|
||||
import { useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link } from "react-router-dom";
|
||||
import { useNotifications, useNotificationsSubscription } from "../hooks/notifications";
|
||||
import type { Database } from "@xtablo/shared-types";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
import { useNotifications, useNotificationsSubscription } from "../hooks/notifications";
|
||||
|
||||
type Notification = Database["public"]["Tables"]["notifications"]["Row"];
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import { supabase } from "../lib/supabase";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import type { Database } from "@xtablo/shared-types";
|
||||
import { supabase } from "../lib/supabase";
|
||||
|
||||
type Notification = Database["public"]["Tables"]["notifications"]["Row"];
|
||||
|
||||
|
|
@ -8,7 +8,12 @@ export function useNotifications() {
|
|||
const queryClient = useQueryClient();
|
||||
|
||||
// Fetch unread notifications
|
||||
const { data: notifications = [], isLoading, error, refetch } = useQuery({
|
||||
const {
|
||||
data: notifications = [],
|
||||
isLoading,
|
||||
error,
|
||||
refetch,
|
||||
} = useQuery({
|
||||
queryKey: ["notifications", "unread"],
|
||||
queryFn: async () => {
|
||||
const { data, error } = await supabase
|
||||
|
|
@ -67,7 +72,11 @@ export function useNotifications() {
|
|||
|
||||
// Hook to fetch all notifications (including read ones)
|
||||
export function useAllNotifications(limit = 50) {
|
||||
const { data: notifications = [], isLoading, error } = useQuery({
|
||||
const {
|
||||
data: notifications = [],
|
||||
isLoading,
|
||||
error,
|
||||
} = useQuery({
|
||||
queryKey: ["notifications", "all", limit],
|
||||
queryFn: async () => {
|
||||
const { data, error } = await supabase
|
||||
|
|
@ -116,4 +125,3 @@ export function useNotificationsSubscription() {
|
|||
|
||||
return { setupSubscription };
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -18,6 +18,7 @@ export type {
|
|||
export type {
|
||||
DragItem,
|
||||
DropResult,
|
||||
Etape,
|
||||
KanbanBoard,
|
||||
KanbanColumn,
|
||||
KanbanColumnUpdate,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,15 @@ import type { RemoveNullFromObject } from "./utils.js";
|
|||
|
||||
export type TaskStatus = "todo" | "in_progress" | "in_review" | "done";
|
||||
|
||||
export type KanbanTask = RemoveNullFromObject<Tables<"tasks_with_assignee">, "id" | "tablo_id">;
|
||||
export type KanbanTask = RemoveNullFromObject<
|
||||
Tables<"tasks_with_assignee">,
|
||||
"id" | "tablo_id" | "is_parent"
|
||||
>;
|
||||
|
||||
export type Etape = RemoveNullFromObject<
|
||||
Tables<"tasks">,
|
||||
"id" | "tablo_id" | "title" | "is_parent"
|
||||
>;
|
||||
|
||||
export interface KanbanColumn {
|
||||
id: string;
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ export function usePublicSlots(api: AxiosInstance, shortUserId: string, standard
|
|||
}>({
|
||||
queryKey: ["public-slots", shortUserId, standardName],
|
||||
queryFn: async () => {
|
||||
const res = await api.get(`/api/public/slots/${shortUserId}/${standardName}`);
|
||||
const res = await api.get(`/api/v1/public/slots/${shortUserId}/${standardName}`);
|
||||
if (res.status !== 200) {
|
||||
throw new Error("Failed to fetch public slots");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue