mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-22 17:31:15 -05:00
Visual edit in Lovable
This commit is contained in:
@@ -9,7 +9,6 @@ import { useToast } from '@/hooks/use-toast';
|
|||||||
import { useAuth } from '@/hooks/useAuth';
|
import { useAuth } from '@/hooks/useAuth';
|
||||||
import { supabase } from '@/integrations/supabase/client';
|
import { supabase } from '@/integrations/supabase/client';
|
||||||
import { Bell, Mail, Smartphone, Volume2 } from 'lucide-react';
|
import { Bell, Mail, Smartphone, Volume2 } from 'lucide-react';
|
||||||
|
|
||||||
interface EmailNotifications {
|
interface EmailNotifications {
|
||||||
review_replies: boolean;
|
review_replies: boolean;
|
||||||
new_followers: boolean;
|
new_followers: boolean;
|
||||||
@@ -17,16 +16,18 @@ interface EmailNotifications {
|
|||||||
weekly_digest: boolean;
|
weekly_digest: boolean;
|
||||||
monthly_digest: boolean;
|
monthly_digest: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PushNotifications {
|
interface PushNotifications {
|
||||||
browser_enabled: boolean;
|
browser_enabled: boolean;
|
||||||
new_content: boolean;
|
new_content: boolean;
|
||||||
social_updates: boolean;
|
social_updates: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function NotificationsTab() {
|
export function NotificationsTab() {
|
||||||
const { user } = useAuth();
|
const {
|
||||||
const { toast } = useToast();
|
user
|
||||||
|
} = useAuth();
|
||||||
|
const {
|
||||||
|
toast
|
||||||
|
} = useToast();
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [emailNotifications, setEmailNotifications] = useState<EmailNotifications>({
|
const [emailNotifications, setEmailNotifications] = useState<EmailNotifications>({
|
||||||
review_replies: true,
|
review_replies: true,
|
||||||
@@ -40,26 +41,20 @@ export function NotificationsTab() {
|
|||||||
new_content: true,
|
new_content: true,
|
||||||
social_updates: true
|
social_updates: true
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchNotificationPreferences();
|
fetchNotificationPreferences();
|
||||||
}, [user]);
|
}, [user]);
|
||||||
|
|
||||||
const fetchNotificationPreferences = async () => {
|
const fetchNotificationPreferences = async () => {
|
||||||
if (!user) return;
|
if (!user) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { data, error } = await supabase
|
const {
|
||||||
.from('user_preferences')
|
data,
|
||||||
.select('email_notifications, push_notifications')
|
error
|
||||||
.eq('user_id', user.id)
|
} = await supabase.from('user_preferences').select('email_notifications, push_notifications').eq('user_id', user.id).maybeSingle();
|
||||||
.maybeSingle();
|
|
||||||
|
|
||||||
if (error && error.code !== 'PGRST116') {
|
if (error && error.code !== 'PGRST116') {
|
||||||
console.error('Error fetching notification preferences:', error);
|
console.error('Error fetching notification preferences:', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
if (data.email_notifications) {
|
if (data.email_notifications) {
|
||||||
setEmailNotifications(data.email_notifications as unknown as EmailNotifications);
|
setEmailNotifications(data.email_notifications as unknown as EmailNotifications);
|
||||||
@@ -75,49 +70,46 @@ export function NotificationsTab() {
|
|||||||
console.error('Error fetching notification preferences:', error);
|
console.error('Error fetching notification preferences:', error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const initializePreferences = async () => {
|
const initializePreferences = async () => {
|
||||||
if (!user) return;
|
if (!user) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { error } = await supabase
|
const {
|
||||||
.from('user_preferences')
|
error
|
||||||
.insert([{
|
} = await supabase.from('user_preferences').insert([{
|
||||||
user_id: user.id,
|
user_id: user.id,
|
||||||
email_notifications: emailNotifications as any,
|
email_notifications: emailNotifications as any,
|
||||||
push_notifications: pushNotifications as any
|
push_notifications: pushNotifications as any
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
if (error) throw error;
|
if (error) throw error;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error initializing preferences:', error);
|
console.error('Error initializing preferences:', error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateEmailNotification = (key: keyof EmailNotifications, value: boolean) => {
|
const updateEmailNotification = (key: keyof EmailNotifications, value: boolean) => {
|
||||||
setEmailNotifications(prev => ({ ...prev, [key]: value }));
|
setEmailNotifications(prev => ({
|
||||||
|
...prev,
|
||||||
|
[key]: value
|
||||||
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
const updatePushNotification = (key: keyof PushNotifications, value: boolean) => {
|
const updatePushNotification = (key: keyof PushNotifications, value: boolean) => {
|
||||||
setPushNotifications(prev => ({ ...prev, [key]: value }));
|
setPushNotifications(prev => ({
|
||||||
|
...prev,
|
||||||
|
[key]: value
|
||||||
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
const saveNotificationPreferences = async () => {
|
const saveNotificationPreferences = async () => {
|
||||||
if (!user) return;
|
if (!user) return;
|
||||||
|
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
const { error } = await supabase
|
const {
|
||||||
.from('user_preferences')
|
error
|
||||||
.upsert([{
|
} = await supabase.from('user_preferences').upsert([{
|
||||||
user_id: user.id,
|
user_id: user.id,
|
||||||
email_notifications: emailNotifications as any,
|
email_notifications: emailNotifications as any,
|
||||||
push_notifications: pushNotifications as any,
|
push_notifications: pushNotifications as any,
|
||||||
updated_at: new Date().toISOString()
|
updated_at: new Date().toISOString()
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
if (error) throw error;
|
if (error) throw error;
|
||||||
|
|
||||||
toast({
|
toast({
|
||||||
title: 'Preferences saved',
|
title: 'Preferences saved',
|
||||||
description: 'Your notification preferences have been updated.'
|
description: 'Your notification preferences have been updated.'
|
||||||
@@ -132,7 +124,6 @@ export function NotificationsTab() {
|
|||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const requestPushPermission = async () => {
|
const requestPushPermission = async () => {
|
||||||
if ('Notification' in window) {
|
if ('Notification' in window) {
|
||||||
const permission = await Notification.requestPermission();
|
const permission = await Notification.requestPermission();
|
||||||
@@ -151,9 +142,7 @@ export function NotificationsTab() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
return <div className="space-y-8">
|
||||||
return (
|
|
||||||
<div className="space-y-8">
|
|
||||||
{/* Email Notifications */}
|
{/* Email Notifications */}
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
@@ -175,10 +164,7 @@ export function NotificationsTab() {
|
|||||||
Get notified when someone replies to your reviews
|
Get notified when someone replies to your reviews
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<Switch
|
<Switch checked={emailNotifications.review_replies} onCheckedChange={checked => updateEmailNotification('review_replies', checked)} />
|
||||||
checked={emailNotifications.review_replies}
|
|
||||||
onCheckedChange={(checked) => updateEmailNotification('review_replies', checked)}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
@@ -188,10 +174,7 @@ export function NotificationsTab() {
|
|||||||
Get notified when someone follows you
|
Get notified when someone follows you
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<Switch
|
<Switch checked={emailNotifications.new_followers} onCheckedChange={checked => updateEmailNotification('new_followers', checked)} />
|
||||||
checked={emailNotifications.new_followers}
|
|
||||||
onCheckedChange={(checked) => updateEmailNotification('new_followers', checked)}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
@@ -201,10 +184,7 @@ export function NotificationsTab() {
|
|||||||
Important updates and announcements from ThrillWiki
|
Important updates and announcements from ThrillWiki
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<Switch
|
<Switch checked={emailNotifications.system_announcements} onCheckedChange={checked => updateEmailNotification('system_announcements', checked)} />
|
||||||
checked={emailNotifications.system_announcements}
|
|
||||||
onCheckedChange={(checked) => updateEmailNotification('system_announcements', checked)}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Separator />
|
<Separator />
|
||||||
@@ -216,10 +196,7 @@ export function NotificationsTab() {
|
|||||||
Weekly summary of new parks, rides, and community activity
|
Weekly summary of new parks, rides, and community activity
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<Switch
|
<Switch checked={emailNotifications.weekly_digest} onCheckedChange={checked => updateEmailNotification('weekly_digest', checked)} />
|
||||||
checked={emailNotifications.weekly_digest}
|
|
||||||
onCheckedChange={(checked) => updateEmailNotification('weekly_digest', checked)}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
@@ -229,10 +206,7 @@ export function NotificationsTab() {
|
|||||||
Monthly roundup of popular content and your activity stats
|
Monthly roundup of popular content and your activity stats
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<Switch
|
<Switch checked={emailNotifications.monthly_digest} onCheckedChange={checked => updateEmailNotification('monthly_digest', checked)} />
|
||||||
checked={emailNotifications.monthly_digest}
|
|
||||||
onCheckedChange={(checked) => updateEmailNotification('monthly_digest', checked)}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -262,30 +236,20 @@ export function NotificationsTab() {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
{!pushNotifications.browser_enabled && (
|
{!pushNotifications.browser_enabled && <Button variant="outline" size="sm" onClick={requestPushPermission}>
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
onClick={requestPushPermission}
|
|
||||||
>
|
|
||||||
Enable
|
Enable
|
||||||
</Button>
|
</Button>}
|
||||||
)}
|
<Switch checked={pushNotifications.browser_enabled} onCheckedChange={checked => {
|
||||||
<Switch
|
|
||||||
checked={pushNotifications.browser_enabled}
|
|
||||||
onCheckedChange={(checked) => {
|
|
||||||
if (!checked) {
|
if (!checked) {
|
||||||
updatePushNotification('browser_enabled', false);
|
updatePushNotification('browser_enabled', false);
|
||||||
} else {
|
} else {
|
||||||
requestPushPermission();
|
requestPushPermission();
|
||||||
}
|
}
|
||||||
}}
|
}} />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{pushNotifications.browser_enabled && (
|
{pushNotifications.browser_enabled && <>
|
||||||
<>
|
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
<Label>New Content</Label>
|
<Label>New Content</Label>
|
||||||
@@ -293,10 +257,7 @@ export function NotificationsTab() {
|
|||||||
Notifications about new parks, rides, and reviews
|
Notifications about new parks, rides, and reviews
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<Switch
|
<Switch checked={pushNotifications.new_content} onCheckedChange={checked => updatePushNotification('new_content', checked)} />
|
||||||
checked={pushNotifications.new_content}
|
|
||||||
onCheckedChange={(checked) => updatePushNotification('new_content', checked)}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
@@ -306,43 +267,17 @@ export function NotificationsTab() {
|
|||||||
Notifications about followers, replies, and mentions
|
Notifications about followers, replies, and mentions
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<Switch
|
<Switch checked={pushNotifications.social_updates} onCheckedChange={checked => updatePushNotification('social_updates', checked)} />
|
||||||
checked={pushNotifications.social_updates}
|
|
||||||
onCheckedChange={(checked) => updatePushNotification('social_updates', checked)}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>}
|
||||||
)}
|
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Separator />
|
|
||||||
|
|
||||||
{/* Sound Settings */}
|
{/* Sound Settings */}
|
||||||
<div className="space-y-4">
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<Volume2 className="w-5 h-5" />
|
|
||||||
<h3 className="text-lg font-medium">Sound Settings</h3>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Card>
|
|
||||||
<CardHeader>
|
|
||||||
<CardDescription>
|
|
||||||
Configure sound preferences for notifications and interactions.
|
|
||||||
</CardDescription>
|
|
||||||
</CardHeader>
|
|
||||||
<CardContent>
|
|
||||||
<div className="text-center p-4 text-muted-foreground">
|
|
||||||
<Volume2 className="w-8 h-8 mx-auto mb-2" />
|
|
||||||
<p className="text-sm">Sound settings coming soon</p>
|
|
||||||
<p className="text-xs mt-1">
|
|
||||||
Configure notification sounds and interaction feedback.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Save Button */}
|
{/* Save Button */}
|
||||||
<div className="flex justify-end">
|
<div className="flex justify-end">
|
||||||
@@ -350,6 +285,5 @@ export function NotificationsTab() {
|
|||||||
{loading ? 'Saving...' : 'Save Notification Preferences'}
|
{loading ? 'Saving...' : 'Save Notification Preferences'}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>;
|
||||||
);
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user