160 lines
No EOL
7 KiB
JavaScript
160 lines
No EOL
7 KiB
JavaScript
import React, { useState } from 'react';
|
|
import { Link } from 'react-router-dom';
|
|
import { motion } from 'framer-motion';
|
|
import { useAuth } from '@/contexts/SupabaseAuthContext';
|
|
import { Button } from '@/components/ui/button';
|
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, DropdownMenuGroup } from '@/components/ui/dropdown-menu';
|
|
import { User, LogOut, Shield, Mail, Loader2 } from 'lucide-react';
|
|
import AeThexLogo from './AeThexLogo';
|
|
import { Input } from './ui/input';
|
|
import { supabase } from '@/lib/customSupabaseClient';
|
|
import { useToast } from './ui/use-toast';
|
|
|
|
const NewsletterForm = () => {
|
|
const [email, setEmail] = useState('');
|
|
const [loading, setLoading] = useState(false);
|
|
const { toast } = useToast();
|
|
|
|
const handleSubmit = async (e) => {
|
|
e.preventDefault();
|
|
setLoading(true);
|
|
const { error } = await supabase.from('newsletter_subscribers').insert({ email });
|
|
if (error) {
|
|
toast({
|
|
variant: 'destructive',
|
|
title: 'Subscription Failed',
|
|
description: error.code === '23505' ? 'This email is already subscribed.' : error.message,
|
|
});
|
|
} else {
|
|
toast({
|
|
title: 'Subscribed!',
|
|
description: 'Thank you for subscribing to the AeThex newsletter.',
|
|
});
|
|
setEmail('');
|
|
}
|
|
setLoading(false);
|
|
};
|
|
|
|
return (
|
|
<form onSubmit={handleSubmit} className="flex flex-col gap-2">
|
|
<p className="font-bold text-white tracking-wider">Stay Updated</p>
|
|
<p className="text-gray-400 text-sm mb-2">Join our newsletter for updates on our progress and new opportunities.</p>
|
|
<div className="flex w-full max-w-sm items-center space-x-2">
|
|
<Input
|
|
type="email"
|
|
placeholder="Email"
|
|
value={email}
|
|
onChange={(e) => setEmail(e.target.value)}
|
|
required
|
|
disabled={loading}
|
|
className="bg-slate-800/50 border-slate-700"
|
|
/>
|
|
<Button type="submit" disabled={loading}>
|
|
{loading ? <Loader2 className="h-4 w-4 animate-spin" /> : 'Subscribe'}
|
|
</Button>
|
|
</div>
|
|
</form>
|
|
);
|
|
};
|
|
|
|
const Footer = ({ onAuthClick }) => {
|
|
const { user, profile, signOut } = useAuth();
|
|
const isAdmin = profile && ['admin', 'site_owner', 'oversee'].includes(profile.role);
|
|
const avatarUrl = profile?.avatar_url || `https://api.dicebear.com/7.x/bottts/svg?seed=${user?.id}`;
|
|
|
|
const UserMenu = () => (
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger asChild>
|
|
<motion.div whileHover={{ scale: 1.05 }} whileTap={{ scale: 0.95 }}>
|
|
<img
|
|
className="h-10 w-10 rounded-full object-cover border-2 border-primary/50 hover:border-primary transition-colors cursor-pointer"
|
|
alt={profile?.username || 'User Avatar'}
|
|
src={avatarUrl}
|
|
/>
|
|
</motion.div>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent
|
|
className="w-64 bg-slate-900/80 border-primary/20 text-white shadow-2xl shadow-primary/10 rounded-xl font-mono backdrop-blur-md mb-2"
|
|
align="end"
|
|
forceMount
|
|
>
|
|
<DropdownMenuLabel className="font-normal p-3">
|
|
<div className="flex flex-col space-y-1">
|
|
<p className="text-sm font-semibold leading-none">{profile?.full_name || profile?.username}</p>
|
|
<p className="text-xs leading-none text-gray-400">{profile?.email}</p>
|
|
</div>
|
|
</DropdownMenuLabel>
|
|
<DropdownMenuSeparator className="bg-primary/10" />
|
|
<DropdownMenuGroup>
|
|
<DropdownMenuItem asChild className="focus:bg-slate-800 focus:text-primary transition-colors cursor-pointer p-3">
|
|
<Link to="/profile">
|
|
<User className="mr-3 h-4 w-4" />
|
|
<span>My Profile</span>
|
|
</Link>
|
|
</DropdownMenuItem>
|
|
{isAdmin && (
|
|
<DropdownMenuItem asChild className="focus:bg-slate-800 focus:text-primary transition-colors cursor-pointer p-3">
|
|
<Link to="/admin">
|
|
<Shield className="mr-3 h-4 w-4" />
|
|
<span>Admin Panel</span>
|
|
</Link>
|
|
</DropdownMenuItem>
|
|
)}
|
|
</DropdownMenuGroup>
|
|
<DropdownMenuSeparator className="bg-primary/10" />
|
|
<DropdownMenuItem onClick={signOut} className="text-red-400 focus:bg-red-900/40 focus:text-red-300 transition-colors cursor-pointer p-3">
|
|
<LogOut className="mr-3 h-4 w-4" />
|
|
<span>Log out</span>
|
|
</DropdownMenuItem>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
);
|
|
|
|
return (
|
|
<footer className="bg-slate-950/80 backdrop-blur-lg border-t border-white/10 font-mono">
|
|
<div className="container mx-auto px-4 py-8">
|
|
<div className="grid grid-cols-1 md:grid-cols-4 gap-8">
|
|
<div className="col-span-1">
|
|
<AeThexLogo className="h-8 mb-4" />
|
|
<p className="text-gray-400 text-sm">Engineering the foundational layers for the next digital epoch.</p>
|
|
</div>
|
|
<div>
|
|
<p className="font-bold text-white mb-4 tracking-wider">Company</p>
|
|
<ul className="space-y-2">
|
|
<li><Link to="/about" className="text-gray-400 hover:text-primary transition-colors">About Us</Link></li>
|
|
<li><Link to="/get-involved" className="text-gray-400 hover:text-primary transition-colors">Get Involved</Link></li>
|
|
<li><Link to="/team" className="text-gray-400 hover:text-primary transition-colors">Our Team</Link></li>
|
|
<li><Link to="/news" className="text-gray-400 hover:text-primary transition-colors">News</Link></li>
|
|
</ul>
|
|
</div>
|
|
<div>
|
|
<p className="font-bold text-white mb-4 tracking-wider">Resources</p>
|
|
<ul className="space-y-2">
|
|
<li><Link to="/technology" className="text-gray-400 hover:text-primary transition-colors">Technology</Link></li>
|
|
<li><Link to="/contact" className="text-gray-400 hover:text-primary transition-colors">Contact</Link></li>
|
|
<li><Link to="/privacy" className="text-gray-400 hover:text-primary transition-colors">Privacy Policy</Link></li>
|
|
<li><Link to="/terms" className="text-gray-400 hover:text-primary transition-colors">Terms & Conditions</Link></li>
|
|
</ul>
|
|
</div>
|
|
<div className="col-span-1">
|
|
<NewsletterForm />
|
|
</div>
|
|
</div>
|
|
<div className="mt-8 pt-8 border-t border-white/10 flex flex-col sm:flex-row justify-between items-center text-gray-500 text-sm">
|
|
<p>© {new Date().getFullYear()} AeThex. All rights reserved.</p>
|
|
<div className="flex items-center gap-4 mt-4 sm:mt-0">
|
|
{user ? (
|
|
<UserMenu />
|
|
) : (
|
|
<Button onClick={onAuthClick} variant="outline" className="border-primary/50 text-primary/80 hover:bg-primary hover:text-slate-900 transition-colors duration-300 text-xs py-1 h-auto">
|
|
Contributor Login
|
|
</Button>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
);
|
|
};
|
|
|
|
export default Footer; |