mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 10:31:13 -05:00
feat: Make Novu settings public
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useAuth } from "@/hooks/useAuth";
|
import { useAuth } from "@/hooks/useAuth";
|
||||||
|
import { usePublicNovuSettings } from "@/hooks/usePublicNovuSettings";
|
||||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||||
import { Label } from "@/components/ui/label";
|
import { Label } from "@/components/ui/label";
|
||||||
import { Switch } from "@/components/ui/switch";
|
import { Switch } from "@/components/ui/switch";
|
||||||
@@ -37,6 +38,7 @@ interface NotificationTemplate {
|
|||||||
|
|
||||||
export function NotificationsTab() {
|
export function NotificationsTab() {
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
|
const { isEnabled: isNovuEnabled, isLoading: isNovuLoading } = usePublicNovuSettings();
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [templates, setTemplates] = useState<NotificationTemplate[]>([]);
|
const [templates, setTemplates] = useState<NotificationTemplate[]>([]);
|
||||||
const [channelPreferences, setChannelPreferences] = useState<ChannelPreferences>({
|
const [channelPreferences, setChannelPreferences] = useState<ChannelPreferences>({
|
||||||
@@ -50,7 +52,6 @@ export function NotificationsTab() {
|
|||||||
digest: 'daily',
|
digest: 'daily',
|
||||||
max_per_hour: 10,
|
max_per_hour: 10,
|
||||||
});
|
});
|
||||||
const isNovuEnabled = notificationService.isEnabled();
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (user) {
|
if (user) {
|
||||||
@@ -168,16 +169,22 @@ export function NotificationsTab() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
{!isNovuEnabled && (
|
{isNovuLoading ? (
|
||||||
|
<Card>
|
||||||
|
<CardHeader>
|
||||||
|
<CardDescription>Loading notification settings...</CardDescription>
|
||||||
|
</CardHeader>
|
||||||
|
</Card>
|
||||||
|
) : !isNovuEnabled ? (
|
||||||
<Card className="border-yellow-500/50 bg-yellow-500/10">
|
<Card className="border-yellow-500/50 bg-yellow-500/10">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="text-yellow-600 dark:text-yellow-400">Novu Not Configured</CardTitle>
|
<CardTitle className="text-yellow-600 dark:text-yellow-400">Novu Not Configured</CardTitle>
|
||||||
<CardDescription>
|
<CardDescription>
|
||||||
Novu notifications are not configured. To enable advanced notifications, add your Novu Application Identifier to the environment variables.
|
Novu notifications are not configured. Contact an administrator to configure the Novu Application Identifier in admin settings.
|
||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
</Card>
|
</Card>
|
||||||
)}
|
) : null}
|
||||||
|
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import { useAuth } from '@/hooks/useAuth';
|
import { useAuth } from '@/hooks/useAuth';
|
||||||
import { useAdminSettings } from '@/hooks/useAdminSettings';
|
import { usePublicNovuSettings } from '@/hooks/usePublicNovuSettings';
|
||||||
|
|
||||||
export function useNovuNotifications() {
|
export function useNovuNotifications() {
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
const { getSettingValue } = useAdminSettings();
|
const { applicationIdentifier, isLoading } = usePublicNovuSettings();
|
||||||
|
|
||||||
const applicationIdentifier = getSettingValue('novu.application_identifier', '');
|
|
||||||
const subscriberId = user?.id;
|
const subscriberId = user?.id;
|
||||||
const isEnabled = !!applicationIdentifier && !!subscriberId;
|
const isEnabled = !!applicationIdentifier && !!subscriberId;
|
||||||
|
|
||||||
@@ -13,5 +12,6 @@ export function useNovuNotifications() {
|
|||||||
applicationIdentifier,
|
applicationIdentifier,
|
||||||
subscriberId,
|
subscriberId,
|
||||||
isEnabled,
|
isEnabled,
|
||||||
|
isLoading,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
30
src/hooks/usePublicNovuSettings.ts
Normal file
30
src/hooks/usePublicNovuSettings.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
import { supabase } from '@/integrations/supabase/client';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook to fetch public Novu settings accessible to all authenticated users
|
||||||
|
*/
|
||||||
|
export function usePublicNovuSettings() {
|
||||||
|
const { data: settings, isLoading, error } = useQuery({
|
||||||
|
queryKey: ['public-novu-settings'],
|
||||||
|
queryFn: async () => {
|
||||||
|
const { data, error } = await supabase
|
||||||
|
.from('admin_settings')
|
||||||
|
.select('setting_key, setting_value')
|
||||||
|
.eq('setting_key', 'novu.application_identifier')
|
||||||
|
.maybeSingle();
|
||||||
|
|
||||||
|
if (error) throw error;
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const applicationIdentifier = settings?.setting_value as string || '';
|
||||||
|
|
||||||
|
return {
|
||||||
|
applicationIdentifier,
|
||||||
|
isLoading,
|
||||||
|
error,
|
||||||
|
isEnabled: !!applicationIdentifier,
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
-- Add policy to allow authenticated users to read Novu application identifier
|
||||||
|
CREATE POLICY "Authenticated users can read novu application identifier"
|
||||||
|
ON admin_settings
|
||||||
|
FOR SELECT
|
||||||
|
TO authenticated
|
||||||
|
USING (setting_key = 'novu.application_identifier');
|
||||||
Reference in New Issue
Block a user