From cd309d30dfab613042ca1a5b93502e37b533d3f8 Mon Sep 17 00:00:00 2001 From: Arthur Belleville Date: Sun, 16 Nov 2025 14:01:41 +0100 Subject: [PATCH] Notifications in the UI --- apps/main/src/components/NavigationBar.tsx | 7 +- .../main/src/components/NotificationPanel.tsx | 292 ++++ .../main/src/components/TabloTasksSection.tsx | 1 + apps/main/src/hooks/notifications.ts | 119 ++ apps/main/src/locales/en/navigation.json | 8 + apps/main/src/locales/fr/navigation.json | 8 + packages/shared-types/src/database.types.ts | 1453 +++++++++-------- xtablo-expo/lib/database.types.ts | 39 + 8 files changed, 1223 insertions(+), 704 deletions(-) create mode 100644 apps/main/src/components/NotificationPanel.tsx create mode 100644 apps/main/src/hooks/notifications.ts diff --git a/apps/main/src/components/NavigationBar.tsx b/apps/main/src/components/NavigationBar.tsx index 752e4e5..ba99c44 100644 --- a/apps/main/src/components/NavigationBar.tsx +++ b/apps/main/src/components/NavigationBar.tsx @@ -37,6 +37,7 @@ import { useLogout } from "../hooks/auth"; import { isProd, isStaging } from "../lib/env"; import { useIsReadOnlyUser, useUser } from "../providers/UserStoreProvider"; import { getXtabloIcon } from "../utils/iconHelpers"; +import { NotificationPanel } from "./NotificationPanel"; import { ThemeSwitcher } from "./ThemeSwitcher"; type NavLinkItem = { @@ -264,10 +265,11 @@ export const SideNavigation = ({ isMobileMenuOpen }: { isMobileMenuOpen: boolean
+
@@ -433,6 +435,9 @@ export function MainNavigation({ isCollapsed }: { isCollapsed: boolean }) { +
  • + +
  • diff --git a/apps/main/src/components/NotificationPanel.tsx b/apps/main/src/components/NotificationPanel.tsx new file mode 100644 index 0000000..1559770 --- /dev/null +++ b/apps/main/src/components/NotificationPanel.tsx @@ -0,0 +1,292 @@ +import { Badge } from "@xtablo/ui/components/badge"; +import { Button } from "@xtablo/ui/components/button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@xtablo/ui/components/dropdown-menu"; +import { + TypographyLarge, + TypographyMuted, + TypographySmall, +} from "@xtablo/ui/components/typography"; +import { + BellIcon, + CheckCheckIcon, + CalendarIcon, + FileTextIcon, + KanbanIcon, + LayoutDashboardIcon, + UserPlusIcon, + MailIcon, + 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"; + +type Notification = Database["public"]["Tables"]["notifications"]["Row"]; + +// Get icon based on entity type +function getNotificationIcon(entityType: string) { + switch (entityType) { + case "tablos": + return ; + case "tasks": + return ; + case "events": + return ; + case "notes": + return ; + case "tablo_access": + return ; + case "tablo_invites": + return ; + default: + return ; + } +} + +// Get link to entity +function getNotificationLink(notification: Notification): string { + const { entity_type, entity_id, metadata } = notification; + + switch (entity_type) { + case "tablos": + return `/tablos/${entity_id}`; + case "tasks": + // If we have tablo_id in metadata, link to the tablo + if (metadata && typeof metadata === "object" && "tablo_id" in metadata) { + return `/tablos/${metadata.tablo_id}`; + } + return "/"; + case "events": + // If we have tablo_id in metadata, link to the tablo events + if (metadata && typeof metadata === "object" && "tablo_id" in metadata) { + return `/tablos/${metadata.tablo_id}`; + } + return "/events"; + case "notes": + return `/notes/${entity_id}`; + case "tablo_access": + case "tablo_invites": + // If we have tablo_id in metadata, link to the tablo + if (metadata && typeof metadata === "object" && "tablo_id" in metadata) { + return `/tablos/${metadata.tablo_id}`; + } + return "/"; + default: + return "/"; + } +} + +// Format relative time +function formatRelativeTime(dateString: string): string { + const date = new Date(dateString); + const now = new Date(); + const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000); + + if (diffInSeconds < 60) { + return "Just now"; + } + + const diffInMinutes = Math.floor(diffInSeconds / 60); + if (diffInMinutes < 60) { + return `${diffInMinutes}m ago`; + } + + const diffInHours = Math.floor(diffInMinutes / 60); + if (diffInHours < 24) { + return `${diffInHours}h ago`; + } + + const diffInDays = Math.floor(diffInHours / 24); + if (diffInDays < 7) { + return `${diffInDays}d ago`; + } + + return date.toLocaleDateString(); +} + +interface NotificationItemProps { + notification: Notification; + onMarkAsRead: (id: string) => void; + onClose: () => void; +} + +function NotificationItem({ notification, onMarkAsRead, onClose }: NotificationItemProps) { + const link = getNotificationLink(notification); + + const handleClick = () => { + onMarkAsRead(notification.id); + onClose(); + }; + + return ( + + +
    +
    +
    + {getNotificationIcon(notification.entity_type)} +
    +
    +
    + + {notification.message} + + + {formatRelativeTime(notification.created_at)} + +
    + +
    +
    + + ); +} + +export function NotificationPanel({ isCollapsed }: { isCollapsed: boolean }) { + const { t } = useTranslation("navigation"); + const { notifications, unreadCount, isLoading, markAsRead, markAllAsRead } = useNotifications(); + const { setupSubscription } = useNotificationsSubscription(); + + // Setup real-time subscription + useEffect(() => { + const cleanup = setupSubscription(); + return cleanup; + }, []); + + return ( + + + + + +
    +
    + + {t("notifications.title", "Notifications")} + + {unreadCount > 0 && ( + {unreadCount} + )} +
    + {unreadCount > 0 && ( + + )} +
    + +
    + {isLoading ? ( +
    + + {t("notifications.loading", "Loading...")} + +
    + ) : notifications.length === 0 ? ( +
    +
    + +
    + + {t("notifications.noNotifications", "No new notifications")} + + + {t("notifications.allCaughtUp", "You're all caught up!")} + +
    + ) : ( +
    + {notifications.map((notification) => ( +
    + { + // Close dropdown - handled by Link navigation + }} + /> +
    + ))} +
    + )} +
    + + {/* {notifications.length > 0 && ( + <> + +
    + + + +
    + + )} */} +
    +
    + ); +} diff --git a/apps/main/src/components/TabloTasksSection.tsx b/apps/main/src/components/TabloTasksSection.tsx index d7a0165..778beab 100644 --- a/apps/main/src/components/TabloTasksSection.tsx +++ b/apps/main/src/components/TabloTasksSection.tsx @@ -164,6 +164,7 @@ export const TabloTasksSection = ({ tablo }: TabloTasksSectionProps) => { isOpen={isModalOpen} onClose={() => setIsModalOpen(false)} members={members} + initialStatus={selectedTask?.status ?? "todo"} /> ); diff --git a/apps/main/src/hooks/notifications.ts b/apps/main/src/hooks/notifications.ts new file mode 100644 index 0000000..2d5c4ab --- /dev/null +++ b/apps/main/src/hooks/notifications.ts @@ -0,0 +1,119 @@ +import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; +import { supabase } from "../lib/supabase"; +import type { Database } from "@xtablo/shared-types"; + +type Notification = Database["public"]["Tables"]["notifications"]["Row"]; + +export function useNotifications() { + const queryClient = useQueryClient(); + + // Fetch unread notifications + const { data: notifications = [], isLoading, error, refetch } = useQuery({ + queryKey: ["notifications", "unread"], + queryFn: async () => { + const { data, error } = await supabase + .from("notifications") + .select("*") + .is("read_at", null) + .order("created_at", { ascending: false }); + + if (error) throw error; + return data as Notification[]; + }, + refetchInterval: 30000, // Refetch every 30 seconds + }); + + // Mark notification as read + const markAsReadMutation = useMutation({ + mutationFn: async (notificationId: string) => { + const { error } = await supabase + .from("notifications") + .update({ read_at: new Date().toISOString() }) + .eq("id", notificationId); + + if (error) throw error; + }, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ["notifications"] }); + }, + }); + + // Mark all notifications as read + const markAllAsReadMutation = useMutation({ + mutationFn: async () => { + const { error } = await supabase + .from("notifications") + .update({ read_at: new Date().toISOString() }) + .is("read_at", null); + + if (error) throw error; + }, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ["notifications"] }); + }, + }); + + return { + notifications, + unreadCount: notifications.length, + isLoading, + error, + refetch, + markAsRead: markAsReadMutation.mutate, + markAllAsRead: markAllAsReadMutation.mutate, + isMarkingAsRead: markAsReadMutation.isPending || markAllAsReadMutation.isPending, + }; +} + +// Hook to fetch all notifications (including read ones) +export function useAllNotifications(limit = 50) { + const { data: notifications = [], isLoading, error } = useQuery({ + queryKey: ["notifications", "all", limit], + queryFn: async () => { + const { data, error } = await supabase + .from("notifications") + .select("*") + .order("created_at", { ascending: false }) + .limit(limit); + + if (error) throw error; + return data as Notification[]; + }, + }); + + return { + notifications, + isLoading, + error, + }; +} + +// Real-time subscription hook +export function useNotificationsSubscription() { + const queryClient = useQueryClient(); + + const setupSubscription = () => { + const channel = supabase + .channel("notifications") + .on( + "postgres_changes", + { + event: "*", + schema: "public", + table: "notifications", + }, + () => { + // Invalidate and refetch notifications when changes occur + queryClient.invalidateQueries({ queryKey: ["notifications"] }); + } + ) + .subscribe(); + + return () => { + supabase.removeChannel(channel); + }; + }; + + return { setupSubscription }; +} + diff --git a/apps/main/src/locales/en/navigation.json b/apps/main/src/locales/en/navigation.json index d456382..c9841bc 100644 --- a/apps/main/src/locales/en/navigation.json +++ b/apps/main/src/locales/en/navigation.json @@ -14,5 +14,13 @@ "settings": "Settings", "availabilities": "Availabilities", "logout": "Sign out" + }, + "notifications": { + "title": "Notifications", + "markAllRead": "Mark all read", + "loading": "Loading...", + "noNotifications": "No new notifications", + "allCaughtUp": "You're all caught up!", + "viewAll": "View all notifications" } } diff --git a/apps/main/src/locales/fr/navigation.json b/apps/main/src/locales/fr/navigation.json index c73eadb..c63ab6d 100644 --- a/apps/main/src/locales/fr/navigation.json +++ b/apps/main/src/locales/fr/navigation.json @@ -14,5 +14,13 @@ "settings": "Paramètres", "availabilities": "Disponibilités", "logout": "Se déconnecter" + }, + "notifications": { + "title": "Notifications", + "markAllRead": "Tout marquer comme lu", + "loading": "Chargement...", + "noNotifications": "Aucune nouvelle notification", + "allCaughtUp": "Vous êtes à jour !", + "viewAll": "Voir toutes les notifications" } } diff --git a/packages/shared-types/src/database.types.ts b/packages/shared-types/src/database.types.ts index c179560..00f3241 100644 --- a/packages/shared-types/src/database.types.ts +++ b/packages/shared-types/src/database.types.ts @@ -1,945 +1,992 @@ -export type Json = string | number | boolean | null | { [key: string]: Json | undefined } | Json[]; +export type Json = + | string + | number + | boolean + | null + | { [key: string]: Json | undefined } + | Json[] export type Database = { // Allows to automatically instantiate createClient with right options // instead of createClient(URL, KEY) __InternalSupabase: { - PostgrestVersion: "13.0.4"; - }; + PostgrestVersion: "13.0.4" + } public: { Tables: { availabilities: { Row: { - availability_data: Json; - created_at: string; - exceptions: Json | null; - id: number; - updated_at: string; - user_id: string; - }; + availability_data: Json + created_at: string + exceptions: Json | null + id: number + updated_at: string + user_id: string + } Insert: { - availability_data?: Json; - created_at?: string; - exceptions?: Json | null; - id?: number; - updated_at?: string; - user_id: string; - }; + availability_data?: Json + created_at?: string + exceptions?: Json | null + id?: number + updated_at?: string + user_id: string + } Update: { - availability_data?: Json; - created_at?: string; - exceptions?: Json | null; - id?: number; - updated_at?: string; - user_id?: string; - }; - Relationships: []; - }; + availability_data?: Json + created_at?: string + exceptions?: Json | null + id?: number + updated_at?: string + user_id?: string + } + Relationships: [] + } calendar_subscriptions: { Row: { - created_at: string | null; - id: string; - tablo_id: string; - token: string; - }; + created_at: string | null + id: string + tablo_id: string + token: string + } Insert: { - created_at?: string | null; - id?: string; - tablo_id: string; - token: string; - }; + created_at?: string | null + id?: string + tablo_id: string + token: string + } Update: { - created_at?: string | null; - id?: string; - tablo_id?: string; - token?: string; - }; + created_at?: string | null + id?: string + tablo_id?: string + token?: string + } Relationships: [ { - foreignKeyName: "calendar_subscriptions_tablo_id_fkey"; - columns: ["tablo_id"]; - isOneToOne: true; - referencedRelation: "events_and_tablos"; - referencedColumns: ["tablo_id"]; + foreignKeyName: "calendar_subscriptions_tablo_id_fkey" + columns: ["tablo_id"] + isOneToOne: true + referencedRelation: "events_and_tablos" + referencedColumns: ["tablo_id"] }, { - foreignKeyName: "calendar_subscriptions_tablo_id_fkey"; - columns: ["tablo_id"]; - isOneToOne: true; - referencedRelation: "tablos"; - referencedColumns: ["id"]; + foreignKeyName: "calendar_subscriptions_tablo_id_fkey" + columns: ["tablo_id"] + isOneToOne: true + referencedRelation: "tablos" + referencedColumns: ["id"] }, { - foreignKeyName: "calendar_subscriptions_tablo_id_fkey"; - columns: ["tablo_id"]; - isOneToOne: true; - referencedRelation: "user_tablos"; - referencedColumns: ["id"]; + foreignKeyName: "calendar_subscriptions_tablo_id_fkey" + columns: ["tablo_id"] + isOneToOne: true + referencedRelation: "user_tablos" + referencedColumns: ["id"] }, - ]; - }; + ] + } devis: { Row: { - client_email: string; - created_at: string; - date: string; - due_date: string; - id: string; - items: Json; - notes: string | null; - number: string; - status: Database["public"]["Enums"]["devis_status"]; - subtotal: number; - tax: number; - terms: string | null; - total: number; - updated_at: string; - user_id: string; - }; + client_email: string + created_at: string + date: string + due_date: string + id: string + items: Json + notes: string | null + number: string + status: Database["public"]["Enums"]["devis_status"] + subtotal: number + tax: number + terms: string | null + total: number + updated_at: string + user_id: string + } Insert: { - client_email: string; - created_at?: string; - date: string; - due_date: string; - id?: string; - items?: Json; - notes?: string | null; - number: string; - status?: Database["public"]["Enums"]["devis_status"]; - subtotal: number; - tax: number; - terms?: string | null; - total: number; - updated_at?: string; - user_id: string; - }; + client_email: string + created_at?: string + date: string + due_date: string + id?: string + items?: Json + notes?: string | null + number: string + status?: Database["public"]["Enums"]["devis_status"] + subtotal: number + tax: number + terms?: string | null + total: number + updated_at?: string + user_id: string + } Update: { - client_email?: string; - created_at?: string; - date?: string; - due_date?: string; - id?: string; - items?: Json; - notes?: string | null; - number?: string; - status?: Database["public"]["Enums"]["devis_status"]; - subtotal?: number; - tax?: number; - terms?: string | null; - total?: number; - updated_at?: string; - user_id?: string; - }; - Relationships: []; - }; + client_email?: string + created_at?: string + date?: string + due_date?: string + id?: string + items?: Json + notes?: string | null + number?: string + status?: Database["public"]["Enums"]["devis_status"] + subtotal?: number + tax?: number + terms?: string | null + total?: number + updated_at?: string + user_id?: string + } + Relationships: [] + } event_types: { Row: { - config: Json; - created_at: string | null; - deleted_at: string | null; - id: string; - is_active: boolean; - standard_name: string | null; - updated_at: string | null; - user_id: string; - }; + config: Json + created_at: string | null + deleted_at: string | null + id: string + is_active: boolean + standard_name: string | null + updated_at: string | null + user_id: string + } Insert: { - config?: Json; - created_at?: string | null; - deleted_at?: string | null; - id?: string; - is_active?: boolean; - standard_name?: string | null; - updated_at?: string | null; - user_id: string; - }; + config?: Json + created_at?: string | null + deleted_at?: string | null + id?: string + is_active?: boolean + standard_name?: string | null + updated_at?: string | null + user_id: string + } Update: { - config?: Json; - created_at?: string | null; - deleted_at?: string | null; - id?: string; - is_active?: boolean; - standard_name?: string | null; - updated_at?: string | null; - user_id?: string; - }; - Relationships: []; - }; + config?: Json + created_at?: string | null + deleted_at?: string | null + id?: string + is_active?: boolean + standard_name?: string | null + updated_at?: string | null + user_id?: string + } + Relationships: [] + } events: { Row: { - created_at: string | null; - created_by: string; - deleted_at: string | null; - description: string | null; - end_time: string | null; - id: string; - start_date: string; - start_time: string; - tablo_id: string; - title: string; - }; + created_at: string | null + created_by: string + deleted_at: string | null + description: string | null + end_time: string | null + id: string + start_date: string + start_time: string + tablo_id: string + title: string + } Insert: { - created_at?: string | null; - created_by: string; - deleted_at?: string | null; - description?: string | null; - end_time?: string | null; - id?: string; - start_date: string; - start_time: string; - tablo_id: string; - title: string; - }; + created_at?: string | null + created_by: string + deleted_at?: string | null + description?: string | null + end_time?: string | null + id?: string + start_date: string + start_time: string + tablo_id: string + title: string + } Update: { - created_at?: string | null; - created_by?: string; - deleted_at?: string | null; - description?: string | null; - end_time?: string | null; - id?: string; - start_date?: string; - start_time?: string; - tablo_id?: string; - title?: string; - }; + created_at?: string | null + created_by?: string + deleted_at?: string | null + description?: string | null + end_time?: string | null + id?: string + start_date?: string + start_time?: string + tablo_id?: string + title?: string + } Relationships: [ { - foreignKeyName: "fk_events_tablo_id"; - columns: ["tablo_id"]; - isOneToOne: false; - referencedRelation: "events_and_tablos"; - referencedColumns: ["tablo_id"]; + foreignKeyName: "fk_events_tablo_id" + columns: ["tablo_id"] + isOneToOne: false + referencedRelation: "events_and_tablos" + referencedColumns: ["tablo_id"] }, { - foreignKeyName: "fk_events_tablo_id"; - columns: ["tablo_id"]; - isOneToOne: false; - referencedRelation: "tablos"; - referencedColumns: ["id"]; + foreignKeyName: "fk_events_tablo_id" + columns: ["tablo_id"] + isOneToOne: false + referencedRelation: "tablos" + referencedColumns: ["id"] }, { - foreignKeyName: "fk_events_tablo_id"; - columns: ["tablo_id"]; - isOneToOne: false; - referencedRelation: "user_tablos"; - referencedColumns: ["id"]; + foreignKeyName: "fk_events_tablo_id" + columns: ["tablo_id"] + isOneToOne: false + referencedRelation: "user_tablos" + referencedColumns: ["id"] }, - ]; - }; + ] + } feedbacks: { Row: { - created_at: string | null; - fd_type: string; - id: number; - message: string; - user_id: string; - }; + created_at: string | null + fd_type: string + id: number + message: string + user_id: string + } Insert: { - created_at?: string | null; - fd_type: string; - id?: number; - message: string; - user_id: string; - }; + created_at?: string | null + fd_type: string + id?: number + message: string + user_id: string + } Update: { - created_at?: string | null; - fd_type?: string; - id?: number; - message?: string; - user_id?: string; - }; - Relationships: []; - }; + created_at?: string | null + fd_type?: string + id?: number + message?: string + user_id?: string + } + Relationships: [] + } note_access: { Row: { - created_at: string | null; - id: number; - is_active: boolean | null; - note_id: string; - tablo_id: string | null; - updated_at: string | null; - user_id: string; - }; + created_at: string | null + id: number + is_active: boolean | null + note_id: string + tablo_id: string | null + updated_at: string | null + user_id: string + } Insert: { - created_at?: string | null; - id?: number; - is_active?: boolean | null; - note_id: string; - tablo_id?: string | null; - updated_at?: string | null; - user_id: string; - }; + created_at?: string | null + id?: number + is_active?: boolean | null + note_id: string + tablo_id?: string | null + updated_at?: string | null + user_id: string + } Update: { - created_at?: string | null; - id?: number; - is_active?: boolean | null; - note_id?: string; - tablo_id?: string | null; - updated_at?: string | null; - user_id?: string; - }; + created_at?: string | null + id?: number + is_active?: boolean | null + note_id?: string + tablo_id?: string | null + updated_at?: string | null + user_id?: string + } Relationships: [ { - foreignKeyName: "fk_note_access_note_id"; - columns: ["note_id"]; - isOneToOne: false; - referencedRelation: "notes"; - referencedColumns: ["id"]; + foreignKeyName: "fk_note_access_note_id" + columns: ["note_id"] + isOneToOne: false + referencedRelation: "notes" + referencedColumns: ["id"] }, { - foreignKeyName: "fk_note_access_tablo_id"; - columns: ["tablo_id"]; - isOneToOne: false; - referencedRelation: "events_and_tablos"; - referencedColumns: ["tablo_id"]; + foreignKeyName: "fk_note_access_tablo_id" + columns: ["tablo_id"] + isOneToOne: false + referencedRelation: "events_and_tablos" + referencedColumns: ["tablo_id"] }, { - foreignKeyName: "fk_note_access_tablo_id"; - columns: ["tablo_id"]; - isOneToOne: false; - referencedRelation: "tablos"; - referencedColumns: ["id"]; + foreignKeyName: "fk_note_access_tablo_id" + columns: ["tablo_id"] + isOneToOne: false + referencedRelation: "tablos" + referencedColumns: ["id"] }, { - foreignKeyName: "fk_note_access_tablo_id"; - columns: ["tablo_id"]; - isOneToOne: false; - referencedRelation: "user_tablos"; - referencedColumns: ["id"]; + foreignKeyName: "fk_note_access_tablo_id" + columns: ["tablo_id"] + isOneToOne: false + referencedRelation: "user_tablos" + referencedColumns: ["id"] }, - ]; - }; + ] + } notes: { Row: { - content: string | null; - created_at: string | null; - deleted_at: string | null; - id: string; - title: string; - updated_at: string | null; - user_id: string; - }; + content: string | null + created_at: string | null + deleted_at: string | null + id: string + title: string + updated_at: string | null + user_id: string + } Insert: { - content?: string | null; - created_at?: string | null; - deleted_at?: string | null; - id?: string; - title: string; - updated_at?: string | null; - user_id: string; - }; + content?: string | null + created_at?: string | null + deleted_at?: string | null + id?: string + title: string + updated_at?: string | null + user_id: string + } Update: { - content?: string | null; - created_at?: string | null; - deleted_at?: string | null; - id?: string; - title?: string; - updated_at?: string | null; - user_id?: string; - }; - Relationships: []; - }; + content?: string | null + created_at?: string | null + deleted_at?: string | null + id?: string + title?: string + updated_at?: string | null + user_id?: string + } + Relationships: [] + } + notifications: { + Row: { + action_type: string + actor_id: string | null + created_at: string + entity_id: string + entity_type: string + id: string + message: string + metadata: Json | null + read_at: string | null + user_id: string + } + Insert: { + action_type: string + actor_id?: string | null + created_at?: string + entity_id: string + entity_type: string + id?: string + message: string + metadata?: Json | null + read_at?: string | null + user_id: string + } + Update: { + action_type?: string + actor_id?: string | null + created_at?: string + entity_id?: string + entity_type?: string + id?: string + message?: string + metadata?: Json | null + read_at?: string | null + user_id?: string + } + Relationships: [] + } profiles: { Row: { - avatar_url: string | null; - email: string | null; - first_name: string | null; - id: string; - is_temporary: boolean; - last_name: string | null; - last_signed_in: string | null; - name: string | null; - plan: Database["public"]["Enums"]["subscription_plan"] | null; - short_user_id: string; - }; + avatar_url: string | null + email: string | null + first_name: string | null + id: string + is_temporary: boolean + last_name: string | null + last_signed_in: string | null + name: string | null + plan: Database["public"]["Enums"]["subscription_plan"] | null + short_user_id: string + } Insert: { - avatar_url?: string | null; - email?: string | null; - first_name?: string | null; - id: string; - is_temporary?: boolean; - last_name?: string | null; - last_signed_in?: string | null; - name?: string | null; - plan?: Database["public"]["Enums"]["subscription_plan"] | null; - short_user_id: string; - }; + avatar_url?: string | null + email?: string | null + first_name?: string | null + id: string + is_temporary?: boolean + last_name?: string | null + last_signed_in?: string | null + name?: string | null + plan?: Database["public"]["Enums"]["subscription_plan"] | null + short_user_id: string + } Update: { - avatar_url?: string | null; - email?: string | null; - first_name?: string | null; - id?: string; - is_temporary?: boolean; - last_name?: string | null; - last_signed_in?: string | null; - name?: string | null; - plan?: Database["public"]["Enums"]["subscription_plan"] | null; - short_user_id?: string; - }; - Relationships: []; - }; + avatar_url?: string | null + email?: string | null + first_name?: string | null + id?: string + is_temporary?: boolean + last_name?: string | null + last_signed_in?: string | null + name?: string | null + plan?: Database["public"]["Enums"]["subscription_plan"] | null + short_user_id?: string + } + Relationships: [] + } shared_notes: { Row: { - created_at: string | null; - is_public: boolean | null; - note_id: string; - updated_at: string | null; - user_id: string; - }; + created_at: string | null + is_public: boolean | null + note_id: string + updated_at: string | null + user_id: string + } Insert: { - created_at?: string | null; - is_public?: boolean | null; - note_id: string; - updated_at?: string | null; - user_id: string; - }; + created_at?: string | null + is_public?: boolean | null + note_id: string + updated_at?: string | null + user_id: string + } Update: { - created_at?: string | null; - is_public?: boolean | null; - note_id?: string; - updated_at?: string | null; - user_id?: string; - }; + created_at?: string | null + is_public?: boolean | null + note_id?: string + updated_at?: string | null + user_id?: string + } Relationships: [ { - foreignKeyName: "fk_shared_notes_note_id"; - columns: ["note_id"]; - isOneToOne: true; - referencedRelation: "notes"; - referencedColumns: ["id"]; + foreignKeyName: "fk_shared_notes_note_id" + columns: ["note_id"] + isOneToOne: true + referencedRelation: "notes" + referencedColumns: ["id"] }, - ]; - }; + ] + } tablo_access: { Row: { - created_at: string | null; - granted_by: string; - id: number; - is_active: boolean | null; - is_admin: boolean | null; - tablo_id: string; - user_id: string; - }; + created_at: string | null + granted_by: string + id: number + is_active: boolean | null + is_admin: boolean | null + tablo_id: string + user_id: string + } Insert: { - created_at?: string | null; - granted_by: string; - id?: number; - is_active?: boolean | null; - is_admin?: boolean | null; - tablo_id: string; - user_id: string; - }; + created_at?: string | null + granted_by: string + id?: number + is_active?: boolean | null + is_admin?: boolean | null + tablo_id: string + user_id: string + } Update: { - created_at?: string | null; - granted_by?: string; - id?: number; - is_active?: boolean | null; - is_admin?: boolean | null; - tablo_id?: string; - user_id?: string; - }; + created_at?: string | null + granted_by?: string + id?: number + is_active?: boolean | null + is_admin?: boolean | null + tablo_id?: string + user_id?: string + } Relationships: [ { - foreignKeyName: "fk_tablo_access_tablo_id"; - columns: ["tablo_id"]; - isOneToOne: false; - referencedRelation: "events_and_tablos"; - referencedColumns: ["tablo_id"]; + foreignKeyName: "fk_tablo_access_tablo_id" + columns: ["tablo_id"] + isOneToOne: false + referencedRelation: "events_and_tablos" + referencedColumns: ["tablo_id"] }, { - foreignKeyName: "fk_tablo_access_tablo_id"; - columns: ["tablo_id"]; - isOneToOne: false; - referencedRelation: "tablos"; - referencedColumns: ["id"]; + foreignKeyName: "fk_tablo_access_tablo_id" + columns: ["tablo_id"] + isOneToOne: false + referencedRelation: "tablos" + referencedColumns: ["id"] }, { - foreignKeyName: "fk_tablo_access_tablo_id"; - columns: ["tablo_id"]; - isOneToOne: false; - referencedRelation: "user_tablos"; - referencedColumns: ["id"]; + foreignKeyName: "fk_tablo_access_tablo_id" + columns: ["tablo_id"] + isOneToOne: false + referencedRelation: "user_tablos" + referencedColumns: ["id"] }, { - foreignKeyName: "fk_tablo_access_user_id_from_profiles"; - columns: ["user_id"]; - isOneToOne: false; - referencedRelation: "profiles"; - referencedColumns: ["id"]; + foreignKeyName: "fk_tablo_access_user_id_from_profiles" + columns: ["user_id"] + isOneToOne: false + referencedRelation: "profiles" + referencedColumns: ["id"] }, - ]; - }; + ] + } tablo_invites: { Row: { - created_at: string; - id: number; - invite_token: string; - invited_by: string; - invited_email: string; - is_pending: boolean; - tablo_id: string; - }; + created_at: string + id: number + invite_token: string + invited_by: string + invited_email: string + is_pending: boolean + tablo_id: string + } Insert: { - created_at?: string; - id?: number; - invite_token: string; - invited_by: string; - invited_email: string; - is_pending?: boolean; - tablo_id: string; - }; + created_at?: string + id?: number + invite_token: string + invited_by: string + invited_email: string + is_pending?: boolean + tablo_id: string + } Update: { - created_at?: string; - id?: number; - invite_token?: string; - invited_by?: string; - invited_email?: string; - is_pending?: boolean; - tablo_id?: string; - }; + created_at?: string + id?: number + invite_token?: string + invited_by?: string + invited_email?: string + is_pending?: boolean + tablo_id?: string + } Relationships: [ { - foreignKeyName: "fk_tablo_invitations_tablo_id"; - columns: ["tablo_id"]; - isOneToOne: false; - referencedRelation: "events_and_tablos"; - referencedColumns: ["tablo_id"]; + foreignKeyName: "fk_tablo_invitations_tablo_id" + columns: ["tablo_id"] + isOneToOne: false + referencedRelation: "events_and_tablos" + referencedColumns: ["tablo_id"] }, { - foreignKeyName: "fk_tablo_invitations_tablo_id"; - columns: ["tablo_id"]; - isOneToOne: false; - referencedRelation: "tablos"; - referencedColumns: ["id"]; + foreignKeyName: "fk_tablo_invitations_tablo_id" + columns: ["tablo_id"] + isOneToOne: false + referencedRelation: "tablos" + referencedColumns: ["id"] }, { - foreignKeyName: "fk_tablo_invitations_tablo_id"; - columns: ["tablo_id"]; - isOneToOne: false; - referencedRelation: "user_tablos"; - referencedColumns: ["id"]; + foreignKeyName: "fk_tablo_invitations_tablo_id" + columns: ["tablo_id"] + isOneToOne: false + referencedRelation: "user_tablos" + referencedColumns: ["id"] }, - ]; - }; + ] + } tablos: { Row: { - color: string | null; - created_at: string | null; - deleted_at: string | null; - id: string; - image: string | null; - name: string; - owner_id: string; - position: number; - status: string; - updated_at: string | null; - }; + color: string | null + created_at: string | null + deleted_at: string | null + id: string + image: string | null + name: string + owner_id: string + position: number + status: string + updated_at: string | null + } Insert: { - color?: string | null; - created_at?: string | null; - deleted_at?: string | null; - id?: string; - image?: string | null; - name: string; - owner_id: string; - position?: number; - status?: string; - updated_at?: string | null; - }; + color?: string | null + created_at?: string | null + deleted_at?: string | null + id?: string + image?: string | null + name: string + owner_id: string + position?: number + status?: string + updated_at?: string | null + } Update: { - color?: string | null; - created_at?: string | null; - deleted_at?: string | null; - id?: string; - image?: string | null; - name?: string; - owner_id?: string; - position?: number; - status?: string; - updated_at?: string | null; - }; - Relationships: []; - }; + color?: string | null + created_at?: string | null + deleted_at?: string | null + id?: string + image?: string | null + name?: string + owner_id?: string + position?: number + status?: string + updated_at?: string | null + } + Relationships: [] + } tasks: { Row: { - assignee_id: string | null; - created_at: string; - description: string | null; - id: string; - position: number; - status: Database["public"]["Enums"]["task_status"]; - tablo_id: string; - title: string; - updated_at: string; - }; + assignee_id: string | null + created_at: string + description: string | null + id: string + position: number + status: Database["public"]["Enums"]["task_status"] + tablo_id: string + title: string + updated_at: string + } Insert: { - assignee_id?: string | null; - created_at?: string; - description?: string | null; - id?: string; - position?: number; - status?: Database["public"]["Enums"]["task_status"]; - tablo_id: string; - title: string; - updated_at?: string; - }; + assignee_id?: string | null + created_at?: string + description?: string | null + id?: string + position?: number + status?: Database["public"]["Enums"]["task_status"] + tablo_id: string + title: string + updated_at?: string + } Update: { - assignee_id?: string | null; - created_at?: string; - description?: string | null; - id?: string; - position?: number; - status?: Database["public"]["Enums"]["task_status"]; - tablo_id?: string; - title?: string; - updated_at?: string; - }; + assignee_id?: string | null + created_at?: string + description?: string | null + id?: string + position?: number + status?: Database["public"]["Enums"]["task_status"] + tablo_id?: string + title?: string + updated_at?: string + } Relationships: [ { - foreignKeyName: "tasks_tablo_id_fkey"; - columns: ["tablo_id"]; - isOneToOne: false; - referencedRelation: "events_and_tablos"; - referencedColumns: ["tablo_id"]; + foreignKeyName: "tasks_tablo_id_fkey" + columns: ["tablo_id"] + isOneToOne: false + referencedRelation: "events_and_tablos" + referencedColumns: ["tablo_id"] }, { - foreignKeyName: "tasks_tablo_id_fkey"; - columns: ["tablo_id"]; - isOneToOne: false; - referencedRelation: "tablos"; - referencedColumns: ["id"]; + foreignKeyName: "tasks_tablo_id_fkey" + columns: ["tablo_id"] + isOneToOne: false + referencedRelation: "tablos" + referencedColumns: ["id"] }, { - foreignKeyName: "tasks_tablo_id_fkey"; - columns: ["tablo_id"]; - isOneToOne: false; - referencedRelation: "user_tablos"; - referencedColumns: ["id"]; + foreignKeyName: "tasks_tablo_id_fkey" + columns: ["tablo_id"] + isOneToOne: false + referencedRelation: "user_tablos" + referencedColumns: ["id"] }, - ]; - }; + ] + } user_introductions: { Row: { - config: Json; - created_at: string | null; - updated_at: string | null; - user_id: string; - }; + config: Json + created_at: string | null + updated_at: string | null + user_id: string + } Insert: { - config?: Json; - created_at?: string | null; - updated_at?: string | null; - user_id: string; - }; + config?: Json + created_at?: string | null + updated_at?: string | null + user_id: string + } Update: { - config?: Json; - created_at?: string | null; - updated_at?: string | null; - user_id?: string; - }; - Relationships: []; - }; - }; + config?: Json + created_at?: string | null + updated_at?: string | null + user_id?: string + } + Relationships: [] + } + } Views: { events_and_tablos: { Row: { - description: string | null; - end_time: string | null; - event_id: string | null; - start_date: string | null; - start_time: string | null; - tablo_color: string | null; - tablo_id: string | null; - tablo_name: string | null; - tablo_status: string | null; - title: string | null; - }; - Relationships: []; - }; + description: string | null + end_time: string | null + event_id: string | null + start_date: string | null + start_time: string | null + tablo_color: string | null + tablo_id: string | null + tablo_name: string | null + tablo_status: string | null + title: string | null + } + Relationships: [] + } tasks_with_assignee: { Row: { - assignee_avatar: string | null; - assignee_id: string | null; - assignee_name: string | null; - created_at: string | null; - description: string | null; - id: string | null; - position: number | null; - status: Database["public"]["Enums"]["task_status"] | null; - tablo_id: string | null; - title: string | null; - updated_at: string | null; - }; + assignee_avatar: string | null + assignee_id: string | null + assignee_name: string | null + created_at: string | null + description: string | null + id: string | null + position: number | null + status: Database["public"]["Enums"]["task_status"] | null + tablo_id: string | null + title: string | null + updated_at: string | null + } Relationships: [ { - foreignKeyName: "tasks_tablo_id_fkey"; - columns: ["tablo_id"]; - isOneToOne: false; - referencedRelation: "events_and_tablos"; - referencedColumns: ["tablo_id"]; + foreignKeyName: "tasks_tablo_id_fkey" + columns: ["tablo_id"] + isOneToOne: false + referencedRelation: "events_and_tablos" + referencedColumns: ["tablo_id"] }, { - foreignKeyName: "tasks_tablo_id_fkey"; - columns: ["tablo_id"]; - isOneToOne: false; - referencedRelation: "tablos"; - referencedColumns: ["id"]; + foreignKeyName: "tasks_tablo_id_fkey" + columns: ["tablo_id"] + isOneToOne: false + referencedRelation: "tablos" + referencedColumns: ["id"] }, { - foreignKeyName: "tasks_tablo_id_fkey"; - columns: ["tablo_id"]; - isOneToOne: false; - referencedRelation: "user_tablos"; - referencedColumns: ["id"]; + foreignKeyName: "tasks_tablo_id_fkey" + columns: ["tablo_id"] + isOneToOne: false + referencedRelation: "user_tablos" + referencedColumns: ["id"] }, - ]; - }; + ] + } user_tablos: { Row: { - access_level: string | null; - color: string | null; - created_at: string | null; - deleted_at: string | null; - id: string | null; - image: string | null; - is_admin: boolean | null; - name: string | null; - position: number | null; - status: string | null; - user_id: string | null; - }; + access_level: string | null + color: string | null + created_at: string | null + deleted_at: string | null + id: string | null + image: string | null + is_admin: boolean | null + name: string | null + position: number | null + status: string | null + user_id: string | null + } Relationships: [ { - foreignKeyName: "fk_tablo_access_user_id_from_profiles"; - columns: ["user_id"]; - isOneToOne: false; - referencedRelation: "profiles"; - referencedColumns: ["id"]; + foreignKeyName: "fk_tablo_access_user_id_from_profiles" + columns: ["user_id"] + isOneToOne: false + referencedRelation: "profiles" + referencedColumns: ["id"] }, - ]; - }; - }; + ] + } + } Functions: { - generate_random_string: { Args: { length?: number }; Returns: string }; + generate_random_string: { Args: { length?: number }; Returns: string } get_my_active_subscription: { - Args: never; + Args: never Returns: { - billing_interval: string; - cancel_at_period_end: boolean; - currency: string; - current_period_end: string; - current_period_start: string; - first_name: string; - last_name: string; - plan: Database["public"]["Enums"]["subscription_plan"]; - product_name: string; - status: string; - subscription_id: string; - unit_amount: number; - user_email: string; - user_id: string; - }[]; - }; + billing_interval: string + cancel_at_period_end: boolean + currency: string + current_period_end: string + current_period_start: string + first_name: string + last_name: string + plan: Database["public"]["Enums"]["subscription_plan"] + product_name: string + status: string + subscription_id: string + unit_amount: number + user_email: string + user_id: string + }[] + } get_stripe_prices: { - Args: never; + Args: never Returns: { - active: boolean; - created: number; - currency: string; - id: string; - metadata: Json; - product: string; - recurring: Json; - unit_amount: number; - }[]; - }; + active: boolean + created: number + currency: string + id: string + metadata: Json + product: string + recurring: Json + unit_amount: number + }[] + } get_stripe_products: { - Args: never; + Args: never Returns: { - active: boolean; - created: number; - description: string; - id: string; - metadata: Json; - name: string; - }[]; - }; + active: boolean + created: number + description: string + id: string + metadata: Json + name: string + }[] + } get_user_stripe_customer: { - Args: never; + Args: never Returns: { - created: number; - email: string; - id: string; - metadata: Json; - user_id: string; - }[]; - }; + created: number + email: string + id: string + metadata: Json + user_id: string + }[] + } get_user_stripe_customer_id: { - Args: { user_uuid: string }; - Returns: string; - }; + Args: { user_uuid: string } + Returns: string + } get_user_stripe_subscriptions: { - Args: never; + Args: never Returns: { - cancel_at_period_end: boolean; - canceled_at: number; - created: number; - current_period_end: number; - current_period_start: number; - customer: string; - id: string; - metadata: Json; - price_id: string; - quantity: number; - status: string; - trial_end: Json; - trial_start: Json; - user_id: string; - }[]; - }; + cancel_at_period_end: boolean + canceled_at: number + created: number + current_period_end: number + current_period_start: number + customer: string + id: string + metadata: Json + price_id: string + quantity: number + status: string + trial_end: Json + trial_start: Json + user_id: string + }[] + } get_user_subscription_status: { - Args: { user_uuid: string }; + Args: { user_uuid: string } Returns: { - cancel_at_period_end: boolean; - current_period_end: number; - current_period_start: number; - plan: Database["public"]["Enums"]["subscription_plan"]; - price_id: string; - product_name: string; - status: string; - subscription_id: string; - }[]; - }; - is_paying_user: { Args: { user_uuid: string }; Returns: boolean }; - }; + cancel_at_period_end: boolean + current_period_end: number + current_period_start: number + plan: Database["public"]["Enums"]["subscription_plan"] + price_id: string + product_name: string + status: string + subscription_id: string + }[] + } + is_paying_user: { Args: { user_uuid: string }; Returns: boolean } + } Enums: { - devis_status: "draft" | "sent" | "accepted" | "rejected" | "expired"; - subscription_plan: "none" | "trial" | "standard"; - task_status: "todo" | "in_progress" | "in_review" | "done"; - }; + devis_status: "draft" | "sent" | "accepted" | "rejected" | "expired" + subscription_plan: "none" | "trial" | "standard" + task_status: "todo" | "in_progress" | "in_review" | "done" + } CompositeTypes: { time_range: { - start_time: string | null; - end_time: string | null; - }; - }; - }; -}; + start_time: string | null + end_time: string | null + } + } + } +} -type DatabaseWithoutInternals = Omit; +type DatabaseWithoutInternals = Omit -type DefaultSchema = DatabaseWithoutInternals[Extract]; +type DefaultSchema = DatabaseWithoutInternals[Extract] export type Tables< DefaultSchemaTableNameOrOptions extends | keyof (DefaultSchema["Tables"] & DefaultSchema["Views"]) | { schema: keyof DatabaseWithoutInternals }, TableName extends DefaultSchemaTableNameOrOptions extends { - schema: keyof DatabaseWithoutInternals; + schema: keyof DatabaseWithoutInternals } ? keyof (DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"] & DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Views"]) : never = never, > = DefaultSchemaTableNameOrOptions extends { - schema: keyof DatabaseWithoutInternals; + schema: keyof DatabaseWithoutInternals } ? (DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"] & DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Views"])[TableName] extends { - Row: infer R; + Row: infer R } ? R : never - : DefaultSchemaTableNameOrOptions extends keyof (DefaultSchema["Tables"] & DefaultSchema["Views"]) - ? (DefaultSchema["Tables"] & DefaultSchema["Views"])[DefaultSchemaTableNameOrOptions] extends { - Row: infer R; + : DefaultSchemaTableNameOrOptions extends keyof (DefaultSchema["Tables"] & + DefaultSchema["Views"]) + ? (DefaultSchema["Tables"] & + DefaultSchema["Views"])[DefaultSchemaTableNameOrOptions] extends { + Row: infer R } ? R : never - : never; + : never export type TablesInsert< DefaultSchemaTableNameOrOptions extends | keyof DefaultSchema["Tables"] | { schema: keyof DatabaseWithoutInternals }, TableName extends DefaultSchemaTableNameOrOptions extends { - schema: keyof DatabaseWithoutInternals; + schema: keyof DatabaseWithoutInternals } ? keyof DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"] : never = never, > = DefaultSchemaTableNameOrOptions extends { - schema: keyof DatabaseWithoutInternals; + schema: keyof DatabaseWithoutInternals } ? DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"][TableName] extends { - Insert: infer I; + Insert: infer I } ? I : never : DefaultSchemaTableNameOrOptions extends keyof DefaultSchema["Tables"] ? DefaultSchema["Tables"][DefaultSchemaTableNameOrOptions] extends { - Insert: infer I; + Insert: infer I } ? I : never - : never; + : never export type TablesUpdate< DefaultSchemaTableNameOrOptions extends | keyof DefaultSchema["Tables"] | { schema: keyof DatabaseWithoutInternals }, TableName extends DefaultSchemaTableNameOrOptions extends { - schema: keyof DatabaseWithoutInternals; + schema: keyof DatabaseWithoutInternals } ? keyof DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"] : never = never, > = DefaultSchemaTableNameOrOptions extends { - schema: keyof DatabaseWithoutInternals; + schema: keyof DatabaseWithoutInternals } ? DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"][TableName] extends { - Update: infer U; + Update: infer U } ? U : never : DefaultSchemaTableNameOrOptions extends keyof DefaultSchema["Tables"] ? DefaultSchema["Tables"][DefaultSchemaTableNameOrOptions] extends { - Update: infer U; + Update: infer U } ? U : never - : never; + : never export type Enums< DefaultSchemaEnumNameOrOptions extends | keyof DefaultSchema["Enums"] | { schema: keyof DatabaseWithoutInternals }, EnumName extends DefaultSchemaEnumNameOrOptions extends { - schema: keyof DatabaseWithoutInternals; + schema: keyof DatabaseWithoutInternals } ? keyof DatabaseWithoutInternals[DefaultSchemaEnumNameOrOptions["schema"]]["Enums"] : never = never, > = DefaultSchemaEnumNameOrOptions extends { - schema: keyof DatabaseWithoutInternals; + schema: keyof DatabaseWithoutInternals } ? DatabaseWithoutInternals[DefaultSchemaEnumNameOrOptions["schema"]]["Enums"][EnumName] : DefaultSchemaEnumNameOrOptions extends keyof DefaultSchema["Enums"] ? DefaultSchema["Enums"][DefaultSchemaEnumNameOrOptions] - : never; + : never export type CompositeTypes< PublicCompositeTypeNameOrOptions extends | keyof DefaultSchema["CompositeTypes"] | { schema: keyof DatabaseWithoutInternals }, CompositeTypeName extends PublicCompositeTypeNameOrOptions extends { - schema: keyof DatabaseWithoutInternals; + schema: keyof DatabaseWithoutInternals } ? keyof DatabaseWithoutInternals[PublicCompositeTypeNameOrOptions["schema"]]["CompositeTypes"] : never = never, > = PublicCompositeTypeNameOrOptions extends { - schema: keyof DatabaseWithoutInternals; + schema: keyof DatabaseWithoutInternals } ? DatabaseWithoutInternals[PublicCompositeTypeNameOrOptions["schema"]]["CompositeTypes"][CompositeTypeName] : PublicCompositeTypeNameOrOptions extends keyof DefaultSchema["CompositeTypes"] ? DefaultSchema["CompositeTypes"][PublicCompositeTypeNameOrOptions] - : never; + : never export const Constants = { public: { @@ -949,4 +996,4 @@ export const Constants = { task_status: ["todo", "in_progress", "in_review", "done"], }, }, -} as const; +} as const diff --git a/xtablo-expo/lib/database.types.ts b/xtablo-expo/lib/database.types.ts index f4043ac..00f3241 100644 --- a/xtablo-expo/lib/database.types.ts +++ b/xtablo-expo/lib/database.types.ts @@ -345,6 +345,45 @@ export type Database = { } Relationships: [] } + notifications: { + Row: { + action_type: string + actor_id: string | null + created_at: string + entity_id: string + entity_type: string + id: string + message: string + metadata: Json | null + read_at: string | null + user_id: string + } + Insert: { + action_type: string + actor_id?: string | null + created_at?: string + entity_id: string + entity_type: string + id?: string + message: string + metadata?: Json | null + read_at?: string | null + user_id: string + } + Update: { + action_type?: string + actor_id?: string | null + created_at?: string + entity_id?: string + entity_type?: string + id?: string + message?: string + metadata?: Json | null + read_at?: string | null + user_id?: string + } + Relationships: [] + } profiles: { Row: { avatar_url: string | null