videofolxtv/client/src/components/ad-settings.tsx
sebastjanartic 395dba2daa Update the website's accent color to a vibrant red hue
Replace all instances of the previous blue accent color with a new red color across various components and pages, including buttons, navigation links, progress bars, and decorative elements.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 946a0075-7e32-454b-b348-9e7f576d7f45
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/60d372ff-2c10-46c7-b01b-10c3435136b0/946a0075-7e32-454b-b348-9e7f576d7f45/ZMEU6bO
2025-09-04 14:32:14 +00:00

324 lines
11 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useState, useEffect } from "react";
import { Settings, DollarSign, TrendingUp, Users, Play } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Switch } from "@/components/ui/switch";
import { Badge } from "@/components/ui/badge";
interface AdNetworkConfig {
id: string;
name: string;
description: string;
status: 'active' | 'inactive' | 'pending';
eCPM: number;
fillRate: number;
priority: number;
vastUrl: string;
}
const AD_NETWORKS: AdNetworkConfig[] = [
{
id: 'publift',
name: 'Publift',
description: 'Agregator več oglaševalskih omrežij (Teads, Primis, Magnite)',
status: 'active',
eCPM: 2.85,
fillRate: 92,
priority: 1,
vastUrl: 'https://publiftvast.example.com/vast'
},
{
id: 'vdo',
name: 'Vdo.ai',
description: 'Napredno AI ciljanje z visokim eCPM',
status: 'active',
eCPM: 3.20,
fillRate: 87,
priority: 2,
vastUrl: 'https://vdo.ai/vast'
},
{
id: 'primis',
name: 'Primis',
description: 'Video discovery platforma z visoko angažiranostjo',
status: 'pending',
eCPM: 2.95,
fillRate: 89,
priority: 3,
vastUrl: 'https://primis.tech/vast'
},
{
id: 'adplayer',
name: 'AdPlayer.Pro',
description: 'Outstream rešitve s sticky in rewarded oglasi',
status: 'inactive',
eCPM: 2.65,
fillRate: 85,
priority: 4,
vastUrl: 'https://adplayer.pro/vast'
},
{
id: 'aniview',
name: 'Aniview',
description: 'Instream, outstream in CTV/OTT format',
status: 'inactive',
eCPM: 3.10,
fillRate: 91,
priority: 5,
vastUrl: 'https://aniview.com/vast'
}
];
interface AdSettingsProps {
isOpen: boolean;
onClose: () => void;
}
export default function AdSettings({ isOpen, onClose }: AdSettingsProps) {
const [networks, setNetworks] = useState<AdNetworkConfig[]>(AD_NETWORKS);
const [globalAdEnabled, setGlobalAdEnabled] = useState(true);
const [totalRevenue, setTotalRevenue] = useState(1247.83);
const [totalImpressions, setTotalImpressions] = useState(45231);
const [averageeCPM, setAverageeCPM] = useState(2.89);
const toggleNetwork = (networkId: string) => {
setNetworks(networks.map(network =>
network.id === networkId
? { ...network, status: network.status === 'active' ? 'inactive' : 'active' }
: network
));
};
const updatePriority = (networkId: string, newPriority: number) => {
setNetworks(networks.map(network =>
network.id === networkId ? { ...network, priority: newPriority } : network
));
};
const getStatusColor = (status: string) => {
switch (status) {
case 'active': return 'bg-green-500';
case 'pending': return 'bg-yellow-500';
case 'inactive': return 'bg-gray-500';
default: return 'bg-gray-500';
}
};
const getStatusText = (status: string) => {
switch (status) {
case 'active': return 'Active';
case 'pending': return 'Pending';
case 'inactive': return 'Inactive';
default: return 'Unknown';
}
};
if (!isOpen) return null;
return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
<div className="bg-white dark:bg-gray-900 rounded-lg max-w-4xl w-full max-h-[90vh] overflow-y-auto">
<div className="sticky top-0 bg-white dark:bg-gray-900 p-6 border-b border-gray-200 dark:border-gray-700">
<div className="flex items-center justify-between">
<div className="flex items-center space-x-3">
<DollarSign className="w-6 h-6 text-[#da234d]" />
<h2 className="text-2xl font-bold text-gray-900 dark:text-white">
Ad Settings
</h2>
</div>
<Button variant="ghost" onClick={onClose}>
×
</Button>
</div>
</div>
<div className="p-6 space-y-6">
{/* Revenue Overview */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-sm font-medium text-gray-600 dark:text-gray-400">
Total Revenue
</CardTitle>
</CardHeader>
<CardContent>
<div className="text-2xl font-bold text-green-600">
{totalRevenue.toFixed(2)}
</div>
<div className="text-xs text-gray-500">
+12.5% this month
</div>
</CardContent>
</Card>
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-sm font-medium text-gray-600 dark:text-gray-400">
Total Impressions
</CardTitle>
</CardHeader>
<CardContent>
<div className="text-2xl font-bold text-[#da234d]">
{totalImpressions.toLocaleString()}
</div>
<div className="text-xs text-gray-500">
+8.2% this month
</div>
</CardContent>
</Card>
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-sm font-medium text-gray-600 dark:text-gray-400">
Average eCPM
</CardTitle>
</CardHeader>
<CardContent>
<div className="text-2xl font-bold text-purple-600">
{averageeCPM.toFixed(2)}
</div>
<div className="text-xs text-gray-500">
+5.7% this month
</div>
</CardContent>
</Card>
</div>
{/* Global Ad Toggle */}
<Card>
<CardHeader>
<CardTitle className="flex items-center justify-between">
<span>Global Ad Settings</span>
<Switch
checked={globalAdEnabled}
onCheckedChange={setGlobalAdEnabled}
/>
</CardTitle>
<CardDescription>
Enable or disable all ads on the video.folx.tv platform
</CardDescription>
</CardHeader>
</Card>
{/* Ad Networks Configuration */}
<Card>
<CardHeader>
<CardTitle>Ad Networks</CardTitle>
<CardDescription>
Configure VAST networks in waterfall order for optimal monetization
</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-4">
{networks
.sort((a, b) => a.priority - b.priority)
.map((network) => (
<div key={network.id} className="flex items-center justify-between p-4 border rounded-lg">
<div className="flex-1">
<div className="flex items-center space-x-3 mb-2">
<h3 className="font-semibold">{network.name}</h3>
<Badge
className={`${getStatusColor(network.status)} text-white text-xs`}
>
{getStatusText(network.status)}
</Badge>
<span className="text-sm text-gray-500">
Prioriteta {network.priority}
</span>
</div>
<p className="text-sm text-gray-600 dark:text-gray-400 mb-2">
{network.description}
</p>
<div className="flex space-x-4 text-sm">
<span className="text-green-600 font-medium">
eCPM: {network.eCPM.toFixed(2)}
</span>
<span className="text-blue-600 font-medium">
Fill Rate: {network.fillRate}%
</span>
</div>
</div>
<div className="flex items-center space-x-2">
<Button
variant="outline"
size="sm"
onClick={() => updatePriority(network.id, network.priority - 1)}
disabled={network.priority === 1}
>
</Button>
<Button
variant="outline"
size="sm"
onClick={() => updatePriority(network.id, network.priority + 1)}
disabled={network.priority === networks.length}
>
</Button>
<Switch
checked={network.status === 'active'}
onCheckedChange={() => toggleNetwork(network.id)}
disabled={network.status === 'pending'}
/>
</div>
</div>
))}
</div>
</CardContent>
</Card>
{/* Integration Guide */}
<Card>
<CardHeader>
<CardTitle>Napredna monetizacija</CardTitle>
<CardDescription>
Navodila za optimizacijo prihodkov z video.folx.tv
</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-3">
<div className="flex items-start space-x-3">
<div className="w-2 h-2 bg-[#da234d] rounded-full mt-2 flex-shrink-0" />
<div>
<h4 className="font-medium">Publift integracija</h4>
<p className="text-sm text-gray-600 dark:text-gray-400">
Multi-network aggregator for revenue increase up to 55%
</p>
</div>
</div>
<div className="flex items-start space-x-3">
<div className="w-2 h-2 bg-green-500 rounded-full mt-2 flex-shrink-0" />
<div>
<h4 className="font-medium">Header bidding</h4>
<p className="text-sm text-gray-600 dark:text-gray-400">
Recommended for 100,000+ monthly views
</p>
</div>
</div>
<div className="flex items-start space-x-3">
<div className="w-2 h-2 bg-purple-500 rounded-full mt-2 flex-shrink-0" />
<div>
<h4 className="font-medium">VAST Waterfall Optimization</h4>
<p className="text-sm text-gray-600 dark:text-gray-400">
Automatic switching between networks for maximum CPMs
</p>
</div>
</div>
</div>
</CardContent>
</Card>
<div className="flex justify-end space-x-3">
<Button variant="outline" onClick={onClose}>
Cancel
</Button>
<Button className="bg-[#da234d] hover:bg-[#da234d]/90">
Save Settings
</Button>
</div>
</div>
</div>
</div>
);
}