Add notifications feature and update feature flags

This update includes creating new files for the notifications feature along with adding two feature flags for enabling notifications and realtime notifications. All the code and package dependencies required for the notifications functionality have been added. The 'pnpm-lock.yaml' has also been updated due to the inclusion of new package dependencies.
This commit is contained in:
giancarlo
2024-04-29 18:12:30 +07:00
parent b78e716298
commit 820ed1f56b
22 changed files with 9857 additions and 10538 deletions

View File

@@ -0,0 +1,2 @@
export * from './use-fetch-notifications';
export * from './use-dismiss-notification';

View File

@@ -0,0 +1,21 @@
import { useCallback } from 'react';
import { useSupabase } from '@kit/supabase/hooks/use-supabase';
export function useDismissNotification() {
const client = useSupabase();
return useCallback(
async (notification: number) => {
const { error } = await client
.from('notifications')
.update({ dismissed: true })
.eq('id', notification);
if (error) {
throw error;
}
},
[client],
);
}

View File

@@ -0,0 +1,91 @@
import { useEffect, useRef } from 'react';
import { useSupabase } from '@kit/supabase/hooks/use-supabase';
type Notification = {
id: number;
body: string;
dismissed: boolean;
type: 'info' | 'warning' | 'error';
created_at: string;
link: string | null;
entity_id: string | null;
entity_type: string | null;
};
export function useFetchNotifications({
onNotifications,
accountIds,
realtime,
}: {
onNotifications: (notifications: Notification[]) => unknown;
accountIds: string[];
realtime: boolean;
}) {
const client = useSupabase();
const didFetchInitialData = useRef(false);
useEffect(() => {
let realtimeSubscription: { unsubscribe: () => void } | null = null;
if (realtime) {
const channel = client.channel('notifications-channel');
realtimeSubscription = channel
.on(
'postgres_changes',
{
event: 'INSERT',
schema: 'public',
filter: `account_id=in.(${accountIds.join(', ')})`,
table: 'notifications',
},
(payload) => {
onNotifications([payload.new as Notification]);
},
)
.subscribe();
}
if (!didFetchInitialData.current) {
const now = new Date().toISOString();
const initialFetch = client
.from('notifications')
.select(
`id,
body,
dismissed,
type,
created_at,
link,
entity_id,
entity_type
`,
)
.in('account_id', accountIds)
.eq('dismissed', false)
.gt('expires_at', now)
.order('created_at', { ascending: false })
.limit(10);
didFetchInitialData.current = true;
void initialFetch.then(({ data, error }) => {
if (error) {
throw error;
}
if (data) {
onNotifications(data);
}
});
}
return () => {
if (realtimeSubscription) {
realtimeSubscription.unsubscribe();
}
};
}, [client, onNotifications, accountIds, realtime]);
}