617 lines
34 KiB
TypeScript
617 lines
34 KiB
TypeScript
"use client";
|
||
|
||
import React, { useEffect, useState, useCallback } from "react";
|
||
import { useRouter } from "next/navigation";
|
||
import axios from "axios";
|
||
import { ApiServerBaseUrl } from "@/utils/baseurl.utils";
|
||
import { getSocialAuthStatus } from "@/utils/commonFunction.utils";
|
||
import {
|
||
Instagram,
|
||
CheckCircle,
|
||
XCircle,
|
||
Link2,
|
||
Users,
|
||
Image as ImageIcon,
|
||
Globe,
|
||
BarChart3,
|
||
Shield,
|
||
Zap,
|
||
ArrowRight,
|
||
ExternalLink,
|
||
RefreshCw
|
||
} from "lucide-react";
|
||
import Link from "next/link";
|
||
|
||
interface Channel {
|
||
_id: string;
|
||
name: string;
|
||
id?: string;
|
||
has_linked_account: boolean;
|
||
}
|
||
|
||
const SocialMediaChannels = () => {
|
||
const router = useRouter();
|
||
|
||
const [channels, setChannels] = useState<Channel[]>([]);
|
||
const [loading, setLoading] = useState(true);
|
||
const [openModal, setOpenModal] = useState(false);
|
||
const [successMsg, setSuccessMsg] = useState("");
|
||
const [connectedChannel, setConnectedChannel] = useState<string | null>(null);
|
||
const [accountData, setAccountData] = useState<any>(null);
|
||
const [refreshing, setRefreshing] = useState(false);
|
||
|
||
// ---------------------------------------------
|
||
// VALIDATE USER ACCESS
|
||
// ---------------------------------------------
|
||
useEffect(() => {
|
||
async function validate() {
|
||
const userEmail = localStorage.getItem("user_email");
|
||
if (!userEmail) {
|
||
router.push("/social-media-connect");
|
||
return;
|
||
}
|
||
|
||
const storedUser = localStorage.getItem("userDetails");
|
||
if (!storedUser) {
|
||
router.push("/social-media-connect");
|
||
return;
|
||
}
|
||
|
||
const user = JSON.parse(storedUser);
|
||
const role = user?.role;
|
||
|
||
if (role === "customer") {
|
||
const session = localStorage.getItem("payment_session");
|
||
if (!session) {
|
||
router.push("/pricing");
|
||
return;
|
||
}
|
||
}
|
||
|
||
const res = await getSocialAuthStatus(userEmail);
|
||
if (!res?.connected) {
|
||
router.push("/social-media-connect");
|
||
return;
|
||
}
|
||
}
|
||
|
||
validate();
|
||
}, [router]);
|
||
|
||
// ---------------------------------------------
|
||
// FETCH CHANNELS
|
||
// ---------------------------------------------
|
||
const loadChannels = useCallback(async () => {
|
||
try {
|
||
const user = localStorage.getItem("user_email");
|
||
const res = await axios.get(`${ApiServerBaseUrl}/social/channels?userId=${user}`);
|
||
const data: Channel[] = res.data || [];
|
||
setChannels(data);
|
||
} catch (err) {
|
||
console.error("Failed to load channels", err);
|
||
} finally {
|
||
setLoading(false);
|
||
}
|
||
}, []);
|
||
|
||
// ---------------------------------------------
|
||
// FETCH ACCOUNT DETAILS
|
||
// ---------------------------------------------
|
||
const loadAccountDetails = useCallback(async () => {
|
||
try {
|
||
const user = localStorage.getItem("user_email");
|
||
const connected = localStorage.getItem("connectedChannel");
|
||
|
||
if (!user || !connected) return;
|
||
|
||
const res = await axios.get(`${ApiServerBaseUrl}/social/account?userId=${user}`);
|
||
setAccountData(res.data || null);
|
||
} catch (err: any) {
|
||
if (err.response?.data?.error !== "Connect a channel first") {
|
||
console.error("Failed to load account details", err);
|
||
}
|
||
setAccountData(null);
|
||
}
|
||
}, []);
|
||
|
||
useEffect(() => {
|
||
loadChannels();
|
||
|
||
const saved = localStorage.getItem("connectedChannel");
|
||
if (saved) {
|
||
setConnectedChannel(saved);
|
||
loadAccountDetails();
|
||
}
|
||
}, [loadChannels, loadAccountDetails]);
|
||
|
||
// ---------------------------------------------
|
||
// CONNECT CHANNEL
|
||
// ---------------------------------------------
|
||
const handleConnectChannel = async (channelId: string, channelName: string) => {
|
||
try {
|
||
const user = localStorage.getItem("user_email");
|
||
|
||
const res = await axios.post(
|
||
`${ApiServerBaseUrl}/social/connect?userId=${user}`,
|
||
{ channel_id: channelId }
|
||
);
|
||
|
||
const savedId = res.data?.data?.channel_id || channelId;
|
||
localStorage.setItem("connectedChannel", savedId);
|
||
setConnectedChannel(savedId);
|
||
|
||
setSuccessMsg(`${channelName} connected successfully!`);
|
||
setOpenModal(false);
|
||
|
||
await loadAccountDetails();
|
||
} catch (err: any) {
|
||
setSuccessMsg(err.response?.data?.error || `Failed to connect ${channelName}`);
|
||
}
|
||
};
|
||
|
||
// ---------------------------------------------
|
||
// REMOVE CHANNEL
|
||
// ---------------------------------------------
|
||
const handleRemoveChannel = () => {
|
||
localStorage.removeItem("connectedChannel");
|
||
setConnectedChannel(null);
|
||
setAccountData(null);
|
||
setSuccessMsg("Channel removed successfully!");
|
||
};
|
||
|
||
// ---------------------------------------------
|
||
// REFRESH DATA
|
||
// ---------------------------------------------
|
||
const handleRefresh = async () => {
|
||
setRefreshing(true);
|
||
await loadAccountDetails();
|
||
setTimeout(() => setRefreshing(false), 1000);
|
||
};
|
||
|
||
return (
|
||
<div className="min-h-screen bg-gradient-to-b from-[#0a0a0a] to-[#111111] p-4 md:p-6 relative overflow-x-hidden">
|
||
{/* Floating background bubbles */}
|
||
<div className="absolute top-20 left-[5%] w-24 h-24 rounded-full bg-pink-500/20 blur-xl animate-float"></div>
|
||
<div className="absolute top-40 right-[10%] w-32 h-32 rounded-full bg-blue-500/15 blur-xl animate-float-slow"></div>
|
||
<div className="absolute bottom-40 left-[20%] w-20 h-20 rounded-full bg-purple-500/20 blur-xl animate-float"></div>
|
||
<div className="absolute bottom-20 right-[15%] w-28 h-28 rounded-full bg-cyan-500/15 blur-xl animate-float-slow"></div>
|
||
|
||
{/* Success Message */}
|
||
{successMsg && (
|
||
<div className="fixed top-4 right-4 z-50">
|
||
<div className={`px-6 py-4 rounded-xl backdrop-blur-xl border ${
|
||
successMsg.includes("success")
|
||
? "bg-green-900/30 border-green-500/30 text-green-400"
|
||
: "bg-red-900/30 border-red-500/30 text-red-400"
|
||
}`}>
|
||
<div className="flex items-center gap-3">
|
||
{successMsg.includes("success") ? (
|
||
<CheckCircle className="w-5 h-5" />
|
||
) : (
|
||
<XCircle className="w-5 h-5" />
|
||
)}
|
||
<span>{successMsg}</span>
|
||
<button
|
||
onClick={() => setSuccessMsg("")}
|
||
className="ml-4 text-gray-400 hover:text-white"
|
||
>
|
||
×
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{/* Main Container */}
|
||
<div className="max-w-6xl mx-auto relative z-10">
|
||
{/* Header */}
|
||
<div className="mb-10">
|
||
<div className="flex flex-col md:flex-row md:items-center justify-between gap-6 mb-8">
|
||
<div className="flex items-center gap-4">
|
||
<div className="relative">
|
||
<div className="w-16 h-16 rounded-2xl bg-gradient-to-br from-pink-500 to-purple-600 flex items-center justify-center shadow-lg shadow-pink-500/30">
|
||
<Instagram className="w-8 h-8 text-white" />
|
||
</div>
|
||
{connectedChannel && (
|
||
<div className="absolute -top-2 -right-2 w-6 h-6 rounded-full bg-green-500 border-2 border-[#111111] flex items-center justify-center">
|
||
<div className="w-2 h-2 rounded-full bg-white"></div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
<div>
|
||
<h1 className="text-3xl md:text-4xl font-bold text-white">
|
||
Instagram Channels
|
||
</h1>
|
||
<p className="text-gray-300 mt-1">
|
||
Manage and connect your Instagram accounts
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Action Buttons */}
|
||
<div className="flex items-center gap-4">
|
||
{connectedChannel && accountData && (
|
||
<button
|
||
onClick={handleRefresh}
|
||
disabled={refreshing}
|
||
className="px-4 py-2 rounded-xl bg-white/5 hover:bg-white/10 border border-white/10 text-gray-300 hover:text-white transition-all duration-300 flex items-center gap-2"
|
||
>
|
||
<RefreshCw className={`w-4 h-4 ${refreshing ? 'animate-spin' : ''}`} />
|
||
Refresh
|
||
</button>
|
||
)}
|
||
{!connectedChannel && (
|
||
<button
|
||
onClick={() => setOpenModal(true)}
|
||
className="px-6 py-3 rounded-xl bg-gradient-to-r from-pink-600 to-purple-600 hover:from-pink-700 hover:to-purple-700 text-white font-semibold transition-all duration-300 hover:scale-105 flex items-center gap-2"
|
||
>
|
||
<Link2 className="w-5 h-5" />
|
||
Connect Channel
|
||
</button>
|
||
)}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Main Content */}
|
||
{connectedChannel && accountData ? (
|
||
<div className="grid lg:grid-cols-3 gap-8">
|
||
{/* Left Column - Profile */}
|
||
<div className="lg:col-span-2 space-y-8">
|
||
{/* Profile Card */}
|
||
<div className="bg-gradient-to-br from-gray-900/90 to-black/90 backdrop-blur-xl rounded-2xl p-8 border border-white/10 shadow-2xl">
|
||
<div className="flex flex-col md:flex-row items-center md:items-start gap-8">
|
||
{/* Profile Image */}
|
||
<div className="relative">
|
||
<img
|
||
src={accountData.profile_picture_url}
|
||
alt={accountData.username || "Instagram profile"}
|
||
className="w-32 h-32 rounded-2xl object-cover border-2 border-white/20 shadow-lg"
|
||
/>
|
||
<div className="absolute -bottom-2 -right-2 w-10 h-10 rounded-full bg-gradient-to-r from-pink-500 to-purple-600 flex items-center justify-center">
|
||
<Instagram className="w-5 h-5 text-white" />
|
||
</div>
|
||
</div>
|
||
|
||
{/* Profile Info */}
|
||
<div className="flex-1">
|
||
<div className="flex flex-col md:flex-row md:items-center justify-between gap-4 mb-6">
|
||
<div>
|
||
<h2 className="text-2xl font-bold text-white">
|
||
{accountData.username}
|
||
</h2>
|
||
{accountData.name && (
|
||
<p className="text-gray-400">{accountData.name}</p>
|
||
)}
|
||
</div>
|
||
<div className="flex items-center gap-3">
|
||
<span className="px-3 py-1 rounded-full bg-green-500/20 text-green-400 text-sm font-medium border border-green-500/30">
|
||
Connected
|
||
</span>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Stats */}
|
||
<div className="grid grid-cols-3 gap-6 mb-6">
|
||
<div className="text-center">
|
||
<div className="text-3xl font-bold text-white">{accountData.media_count}</div>
|
||
<div className="text-gray-400 text-sm">Posts</div>
|
||
</div>
|
||
<div className="text-center">
|
||
<div className="text-3xl font-bold text-white">{accountData.followers_count}</div>
|
||
<div className="text-gray-400 text-sm">Followers</div>
|
||
</div>
|
||
<div className="text-center">
|
||
<div className="text-3xl font-bold text-white">{accountData.follows_count}</div>
|
||
<div className="text-gray-400 text-sm">Following</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Bio */}
|
||
{accountData.biography && (
|
||
<div className="mb-6">
|
||
<h3 className="text-white font-semibold mb-2">Bio</h3>
|
||
<p className="text-gray-300 whitespace-pre-line">{accountData.biography}</p>
|
||
</div>
|
||
)}
|
||
|
||
{/* Website */}
|
||
{accountData.website && (
|
||
<a
|
||
href={accountData.website}
|
||
target="_blank"
|
||
rel="noopener noreferrer"
|
||
className="inline-flex items-center gap-2 text-blue-400 hover:text-blue-300 transition-colors"
|
||
>
|
||
<Globe className="w-4 h-4" />
|
||
<span>{accountData.website}</span>
|
||
<ExternalLink className="w-3 h-3" />
|
||
</a>
|
||
)}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Quick Actions */}
|
||
<div className="bg-gradient-to-br from-gray-900/90 to-black/90 backdrop-blur-xl rounded-2xl p-6 border border-white/10 shadow-2xl">
|
||
<h3 className="text-xl font-bold text-white mb-6 flex items-center gap-3">
|
||
<Zap className="w-5 h-5 text-yellow-400" />
|
||
Quick Actions
|
||
</h3>
|
||
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
|
||
<Link
|
||
href="/social-media-posts"
|
||
className="p-4 rounded-xl bg-white/5 hover:bg-white/10 border border-white/10 transition-all duration-300 hover:scale-105 group"
|
||
>
|
||
<div className="flex items-center gap-3 mb-2">
|
||
<ImageIcon className="w-6 h-6 text-pink-400" />
|
||
<span className="text-white font-medium">Media Library</span>
|
||
</div>
|
||
<p className="text-gray-400 text-sm">View and manage your posts</p>
|
||
</Link>
|
||
<Link
|
||
href="/comments"
|
||
className="p-4 rounded-xl bg-white/5 hover:bg-white/10 border border-white/10 transition-all duration-300 hover:scale-105 group"
|
||
>
|
||
<div className="flex items-center gap-3 mb-2">
|
||
<Users className="w-6 h-6 text-blue-400" />
|
||
<span className="text-white font-medium">Comments</span>
|
||
</div>
|
||
<p className="text-gray-400 text-sm">Manage comments & engagement</p>
|
||
</Link>
|
||
<Link
|
||
href="/insights"
|
||
className="p-4 rounded-xl bg-white/5 hover:bg-white/10 border border-white/10 transition-all duration-300 hover:scale-105 group"
|
||
>
|
||
<div className="flex items-center gap-3 mb-2">
|
||
<BarChart3 className="w-6 h-6 text-green-400" />
|
||
<span className="text-white font-medium">Insights</span>
|
||
</div>
|
||
<p className="text-gray-400 text-sm">View performance analytics</p>
|
||
</Link>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Right Column - Settings & Info */}
|
||
<div className="space-y-8">
|
||
{/* Connection Status */}
|
||
<div className="bg-gradient-to-br from-gray-900/90 to-black/90 backdrop-blur-xl rounded-2xl p-6 border border-white/10 shadow-2xl">
|
||
<h3 className="text-xl font-bold text-white mb-4">Channel Status</h3>
|
||
<div className="space-y-6">
|
||
<div className="flex items-center justify-between p-4 rounded-xl bg-white/5">
|
||
<div className="flex items-center gap-3">
|
||
<Instagram className="w-6 h-6 text-pink-400" />
|
||
<span className="text-white">Instagram Account</span>
|
||
</div>
|
||
<div className="px-3 py-1 rounded-full text-sm font-medium bg-green-500/20 text-green-400 border border-green-500/30">
|
||
Connected
|
||
</div>
|
||
</div>
|
||
|
||
<div className="space-y-3">
|
||
<div className="flex items-center justify-between text-sm">
|
||
<span className="text-gray-400">Media Access</span>
|
||
<span className="text-green-400">✓ Available</span>
|
||
</div>
|
||
<div className="flex items-center justify-between text-sm">
|
||
<span className="text-gray-400">Comment Access</span>
|
||
<span className="text-green-400">✓ Available</span>
|
||
</div>
|
||
<div className="flex items-center justify-between text-sm">
|
||
<span className="text-gray-400">Insights Access</span>
|
||
<span className="text-green-400">✓ Available</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="pt-4 border-t border-white/10">
|
||
<button
|
||
onClick={handleRemoveChannel}
|
||
className="w-full py-3 rounded-xl bg-gradient-to-r from-red-600 to-red-700 hover:from-red-700 hover:to-red-800 text-white font-medium transition-all duration-300 hover:scale-105 flex items-center justify-center gap-2"
|
||
>
|
||
<Link2 className="w-4 h-4" />
|
||
Disconnect Channel
|
||
</button>
|
||
<p className="text-gray-400 text-xs text-center mt-2">
|
||
This will revoke Social Buddy's access to this account
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Info Card */}
|
||
<div className="bg-gradient-to-br from-blue-900/20 to-indigo-900/20 rounded-2xl p-6 border border-blue-500/30 backdrop-blur-xl">
|
||
<h4 className="text-lg font-semibold text-white mb-4 flex items-center gap-2">
|
||
<Shield className="w-5 h-5 text-blue-400" />
|
||
Channel Information
|
||
</h4>
|
||
<ul className="space-y-3 text-sm">
|
||
<li className="flex items-start gap-2 text-gray-300">
|
||
<CheckCircle className="w-4 h-4 text-green-400 flex-shrink-0 mt-0.5" />
|
||
<span>All data is synced securely</span>
|
||
</li>
|
||
<li className="flex items-start gap-2 text-gray-300">
|
||
<CheckCircle className="w-4 h-4 text-green-400 flex-shrink-0 mt-0.5" />
|
||
<span>Manual management only</span>
|
||
</li>
|
||
<li className="flex items-start gap-2 text-gray-300">
|
||
<CheckCircle className="w-4 h-4 text-green-400 flex-shrink-0 mt-0.5" />
|
||
<span>Real-time data updates</span>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
) : (
|
||
/* No Channel Connected State */
|
||
<div className="flex flex-col items-center justify-center py-20">
|
||
<div className="w-32 h-32 rounded-2xl bg-gradient-to-br from-gray-900 to-black border border-white/10 flex items-center justify-center mb-8">
|
||
<Instagram className="w-16 h-16 text-gray-400" />
|
||
</div>
|
||
<h2 className="text-2xl font-bold text-white mb-4">No Channel Connected</h2>
|
||
<p className="text-gray-400 text-center max-w-md mb-8">
|
||
Connect an Instagram account to access media management, insights, and comment tools.
|
||
</p>
|
||
<button
|
||
onClick={() => setOpenModal(true)}
|
||
className="px-8 py-4 rounded-xl bg-gradient-to-r from-pink-600 to-purple-600 hover:from-pink-700 hover:to-purple-700 text-white font-semibold text-lg transition-all duration-300 hover:scale-105 flex items-center gap-3"
|
||
>
|
||
<Link2 className="w-6 h-6" />
|
||
Connect Instagram Channel
|
||
<ArrowRight className="w-5 h-5" />
|
||
</button>
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
{/* Channel Selection Modal */}
|
||
{openModal && (
|
||
<div className="fixed inset-0 bg-black/70 backdrop-blur-sm flex items-center justify-center p-4 z-50">
|
||
<div className="bg-gradient-to-br from-gray-900 to-black backdrop-blur-xl rounded-2xl border border-white/10 shadow-2xl w-full max-w-4xl max-h-[90vh] overflow-hidden flex flex-col">
|
||
{/* Modal Header */}
|
||
<div className="p-6 border-b border-white/10">
|
||
<div className="flex items-center justify-between">
|
||
<div>
|
||
<h2 className="text-2xl font-bold text-white">Connect Instagram Channel</h2>
|
||
<p className="text-gray-400 mt-1">Select an Instagram account to connect</p>
|
||
</div>
|
||
<button
|
||
onClick={() => setOpenModal(false)}
|
||
className="w-8 h-8 rounded-full bg-white/10 hover:bg-white/20 flex items-center justify-center text-gray-400 hover:text-white transition-colors"
|
||
>
|
||
×
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Modal Content */}
|
||
<div className="p-6 flex-1 overflow-y-auto">
|
||
{loading ? (
|
||
<div className="flex items-center justify-center py-20">
|
||
<div className="animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-pink-500"></div>
|
||
</div>
|
||
) : channels.length === 0 ? (
|
||
<div className="text-center py-20">
|
||
<Instagram className="w-16 h-16 text-gray-400 mx-auto mb-4" />
|
||
<p className="text-gray-400">No Instagram channels available</p>
|
||
<p className="text-gray-500 text-sm mt-2">Make sure your Instagram account is linked to Facebook</p>
|
||
</div>
|
||
) : (
|
||
<div className="grid gap-6 grid-cols-1 md:grid-cols-2">
|
||
{channels.map((channel) => (
|
||
<div
|
||
key={channel.id}
|
||
className="bg-gradient-to-br from-gray-900/50 to-black/50 backdrop-blur-sm rounded-2xl p-6 border border-white/10 hover:border-pink-500/30 transition-all duration-300 hover:scale-[1.02] group"
|
||
>
|
||
<div className="flex items-center gap-4 mb-4">
|
||
<div className={`w-12 h-12 rounded-xl flex items-center justify-center ${
|
||
channel.has_linked_account
|
||
? "bg-gradient-to-br from-pink-500/20 to-purple-600/20"
|
||
: "bg-gray-800/50"
|
||
}`}>
|
||
<Instagram className={`w-6 h-6 ${
|
||
channel.has_linked_account ? "text-pink-400" : "text-gray-400"
|
||
}`} />
|
||
</div>
|
||
<div>
|
||
<h3 className="text-xl font-bold text-white">{channel.name}</h3>
|
||
<div className={`mt-1 text-sm ${
|
||
channel.has_linked_account
|
||
? "text-green-400 flex items-center gap-1"
|
||
: "text-orange-400 flex items-center gap-1"
|
||
}`}>
|
||
{channel.has_linked_account ? (
|
||
<>
|
||
<CheckCircle className="w-4 h-4" />
|
||
Ready to connect
|
||
</>
|
||
) : (
|
||
<>
|
||
<XCircle className="w-4 h-4" />
|
||
Requires authorization
|
||
</>
|
||
)}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<p className="text-gray-400 text-sm mb-6">
|
||
{channel.has_linked_account
|
||
? "Connect this Instagram account to access media, insights, and comments."
|
||
: "This account needs to be authorized through Facebook first."
|
||
}
|
||
</p>
|
||
|
||
<button
|
||
onClick={() => channel.has_linked_account && handleConnectChannel(channel.id!, channel.name)}
|
||
disabled={!channel.has_linked_account}
|
||
className={`w-full py-3 rounded-xl font-semibold transition-all duration-300 flex items-center justify-center gap-2 ${
|
||
channel.has_linked_account
|
||
? "bg-gradient-to-r from-pink-600 to-purple-600 hover:from-pink-700 hover:to-purple-700 text-white hover:scale-105"
|
||
: "bg-gray-800 text-gray-500 cursor-not-allowed"
|
||
}`}
|
||
>
|
||
{channel.has_linked_account ? (
|
||
<>
|
||
<Link2 className="w-5 h-5" />
|
||
Connect Channel
|
||
<ArrowRight className="w-4 h-4" />
|
||
</>
|
||
) : (
|
||
"Authorization Required"
|
||
)}
|
||
</button>
|
||
</div>
|
||
))}
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
{/* Modal Footer */}
|
||
<div className="p-6 border-t border-white/10">
|
||
<div className="flex justify-between items-center">
|
||
<p className="text-gray-400 text-sm">
|
||
{channels.length} channel{channels.length !== 1 ? 's' : ''} available
|
||
</p>
|
||
<button
|
||
onClick={() => setOpenModal(false)}
|
||
className="px-6 py-2 rounded-xl bg-white/10 hover:bg-white/20 text-gray-300 hover:text-white font-medium transition-colors"
|
||
>
|
||
Cancel
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{/* Animation Styles */}
|
||
<style jsx>{`
|
||
@keyframes float {
|
||
0%, 100% {
|
||
transform: translateY(0) translateX(0);
|
||
}
|
||
50% {
|
||
transform: translateY(-20px) translateX(10px);
|
||
}
|
||
}
|
||
@keyframes float-slow {
|
||
0%, 100% {
|
||
transform: translateY(0) translateX(0);
|
||
}
|
||
50% {
|
||
transform: translateY(-30px) translateX(-15px);
|
||
}
|
||
}
|
||
.animate-float {
|
||
animation: float 8s ease-in-out infinite;
|
||
}
|
||
.animate-float-slow {
|
||
animation: float-slow 10s ease-in-out infinite;
|
||
}
|
||
`}</style>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default SocialMediaChannels; |