Files
thrilltrack-explorer/src-old/hooks/useBanCheck.ts

134 lines
4.4 KiB
TypeScript

import { useEffect, useState } from 'react';
import { useAuth } from '@/hooks/useAuth';
import { supabase } from '@/lib/supabaseClient';
import { useNavigate } from 'react-router-dom';
import { toast } from '@/hooks/use-toast';
import { logger } from '@/lib/logger';
export function useBanCheck() {
const { user } = useAuth();
const navigate = useNavigate();
const [isBanned, setIsBanned] = useState(false);
const [banReason, setBanReason] = useState<string | null>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
if (!user) {
setIsBanned(false);
setLoading(false);
return;
}
const checkBan = async () => {
try {
const { data: profile } = await supabase
.from('profiles')
.select('banned, ban_reason, ban_expires_at')
.eq('user_id', user.id)
.single();
if (profile?.banned) {
setIsBanned(true);
setBanReason(profile.ban_reason || null);
const reason = profile.ban_reason
? `Reason: ${profile.ban_reason}`
: 'Contact support for assistance.';
// Add expiration info
let expirationText = '';
if (profile.ban_expires_at) {
const expiresAt = new Date(profile.ban_expires_at);
const now = new Date();
const daysLeft = Math.ceil((expiresAt.getTime() - now.getTime()) / (1000 * 60 * 60 * 24));
expirationText = ` This ban will expire in ${daysLeft} day${daysLeft !== 1 ? 's' : ''}.`;
} else {
expirationText = ' This is a permanent ban.';
}
toast({
title: 'Account Suspended',
description: `Your account has been suspended. ${reason}${expirationText}`,
variant: 'destructive',
duration: Infinity // Don't auto-dismiss
});
// Sign out banned user
await supabase.auth.signOut();
navigate('/');
}
} catch (error) {
// Silent - ban check failure is non-critical, user proceeds normally
} finally {
setLoading(false);
}
};
checkBan();
// Subscribe to profile changes (real-time ban/unban detection)
const channel = supabase
.channel('ban-check')
.on(
'postgres_changes',
{
event: 'UPDATE',
schema: 'public',
table: 'profiles',
filter: `user_id=eq.${user.id}`
},
(payload) => {
const newProfile = payload.new as { banned: boolean; ban_reason: string | null; ban_expires_at: string | null };
// Handle BAN event
if (newProfile.banned && !isBanned) {
setIsBanned(true);
setBanReason(newProfile.ban_reason || null);
const reason = newProfile.ban_reason
? `Reason: ${newProfile.ban_reason}`
: 'Contact support for assistance.';
// Add expiration info
let expirationText = '';
if (newProfile.ban_expires_at) {
const expiresAt = new Date(newProfile.ban_expires_at);
const now = new Date();
const daysLeft = Math.ceil((expiresAt.getTime() - now.getTime()) / (1000 * 60 * 60 * 24));
expirationText = ` This ban will expire in ${daysLeft} day${daysLeft !== 1 ? 's' : ''}.`;
} else {
expirationText = ' This is a permanent ban.';
}
toast({
title: 'Account Suspended',
description: `Your account has been suspended. ${reason}${expirationText}`,
variant: 'destructive',
duration: Infinity
});
supabase.auth.signOut();
navigate('/');
}
// Handle UNBAN event
if (!newProfile.banned && isBanned) {
setIsBanned(false);
setBanReason(null);
toast({
title: 'Account Restored',
description: 'Your account has been unbanned. You can now use the application normally.',
variant: 'default',
duration: 8000
});
}
}
)
.subscribe();
return () => {
supabase.removeChannel(channel);
};
}, [user, navigate]);
return { isBanned, loading, banReason };
}