|
|
import React, { useState } from 'react'; |
|
|
import { motion } from 'framer-motion'; |
|
|
import { |
|
|
Link2, |
|
|
Check, |
|
|
X, |
|
|
ExternalLink, |
|
|
Settings, |
|
|
RefreshCw, |
|
|
Shield, |
|
|
Key, |
|
|
AlertCircle, |
|
|
CheckCircle, |
|
|
Linkedin, |
|
|
Palette, |
|
|
Zap, |
|
|
ArrowRight, |
|
|
Info, |
|
|
Save |
|
|
} from 'lucide-react'; |
|
|
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card'; |
|
|
import { Button } from '@/components/ui/button'; |
|
|
import { Badge } from '@/components/ui/badge'; |
|
|
import { Switch } from '@/components/ui/switch'; |
|
|
import { Label } from '@/components/ui/label'; |
|
|
import { Input } from '@/components/ui/input'; |
|
|
import { Separator } from '@/components/ui/separator'; |
|
|
import { |
|
|
Dialog, |
|
|
DialogContent, |
|
|
DialogHeader, |
|
|
DialogTitle, |
|
|
DialogTrigger, |
|
|
DialogDescription, |
|
|
} from '@/components/ui/dialog'; |
|
|
import { |
|
|
Alert, |
|
|
AlertDescription, |
|
|
AlertTitle, |
|
|
} from '@/components/ui/alert'; |
|
|
|
|
|
const integrations = [ |
|
|
{ |
|
|
id: 'linkedin', |
|
|
name: 'LinkedIn', |
|
|
description: 'Connect your LinkedIn account to schedule and publish posts directly', |
|
|
icon: Linkedin, |
|
|
color: 'blue', |
|
|
bgColor: 'bg-[#0A66C2]', |
|
|
connected: true, |
|
|
account: 'alex.business@company.com', |
|
|
lastSync: '2 mins ago', |
|
|
features: [ |
|
|
'Schedule posts up to 60 days in advance', |
|
|
'Publish carousel, image, and text posts', |
|
|
'Track post performance analytics', |
|
|
'Manage multiple company pages' |
|
|
] |
|
|
}, |
|
|
{ |
|
|
id: 'canva', |
|
|
name: 'Canva', |
|
|
description: 'Import designs directly from your Canva workspace for post visuals', |
|
|
icon: Palette, |
|
|
color: 'purple', |
|
|
bgColor: 'bg-gradient-to-br from-[#00C4CC] to-[#7B2FF7]', |
|
|
connected: false, |
|
|
account: null, |
|
|
lastSync: null, |
|
|
features: [ |
|
|
'Browse and import Canva designs', |
|
|
'Access brand kit assets', |
|
|
'Import templates for carousels', |
|
|
'Sync design updates automatically' |
|
|
] |
|
|
}, |
|
|
]; |
|
|
|
|
|
export default function Integrations() { |
|
|
const [linkedInDialogOpen, setLinkedInDialogOpen] = useState(false); |
|
|
const [canvaDialogOpen, setCanvaDialogOpen] = useState(false); |
|
|
const [autoPost, setAutoPost] = useState(true); |
|
|
const [notifications, setNotifications] = useState(true); |
|
|
|
|
|
return ( |
|
|
<div className="min-h-screen bg-gradient-to-br from-slate-50 via-white to-blue-50/30"> |
|
|
<div className="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 py-8"> |
|
|
{/* Header */} |
|
|
<motion.div |
|
|
initial={{ opacity: 0, y: -20 }} |
|
|
animate={{ opacity: 1, y: 0 }} |
|
|
className="mb-8" |
|
|
> |
|
|
<div className="flex flex-col md:flex-row md:items-center md:justify-between gap-4"> |
|
|
<div> |
|
|
<h1 className="text-3xl font-bold text-slate-900 tracking-tight"> |
|
|
Integrations |
|
|
</h1> |
|
|
<p className="text-slate-500 mt-1"> |
|
|
Connect your tools to streamline your content workflow |
|
|
</p> |
|
|
</div> |
|
|
</div> |
|
|
</motion.div> |
|
|
|
|
|
{/* Integration Status Banner */} |
|
|
<motion.div |
|
|
initial={{ opacity: 0, y: 10 }} |
|
|
animate={{ opacity: 1, y: 0 }} |
|
|
className="mb-8" |
|
|
> |
|
|
<Alert className="border-blue-200 bg-blue-50"> |
|
|
<Info className="h-4 w-4 text-blue-600" /> |
|
|
<AlertTitle className="text-blue-800">Quick Setup</AlertTitle> |
|
|
<AlertDescription className="text-blue-700"> |
|
|
Connect both LinkedIn and Canva to unlock the full potential of automated content scheduling. Your designs will flow seamlessly to your LinkedIn audience. |
|
|
</AlertDescription> |
|
|
</Alert> |
|
|
</motion.div> |
|
|
|
|
|
{/* Integration Cards */} |
|
|
<div className="space-y-6"> |
|
|
{integrations.map((integration, index) => ( |
|
|
<motion.div |
|
|
key={integration.id} |
|
|
initial={{ opacity: 0, y: 20 }} |
|
|
animate={{ opacity: 1, y: 0 }} |
|
|
transition={{ delay: index * 0.1 }} |
|
|
> |
|
|
<Card className="border-0 shadow-lg shadow-slate-200/50 overflow-hidden"> |
|
|
<CardContent className="p-0"> |
|
|
<div className="flex flex-col lg:flex-row"> |
|
|
{/* Left Section - Integration Info */} |
|
|
<div className="flex-1 p-6"> |
|
|
<div className="flex items-start gap-4"> |
|
|
<div className={`w-14 h-14 rounded-xl ${integration.bgColor} flex items-center justify-center shadow-lg`}> |
|
|
<integration.icon className="w-7 h-7 text-white" /> |
|
|
</div> |
|
|
<div className="flex-1"> |
|
|
<div className="flex items-center gap-3"> |
|
|
<h3 className="text-xl font-semibold text-slate-900"> |
|
|
{integration.name} |
|
|
</h3> |
|
|
{integration.connected ? ( |
|
|
<Badge className="bg-emerald-100 text-emerald-700 border-0 gap-1"> |
|
|
<CheckCircle className="w-3 h-3" /> |
|
|
Connected |
|
|
</Badge> |
|
|
) : ( |
|
|
<Badge variant="outline" className="text-slate-500 border-slate-300"> |
|
|
Not Connected |
|
|
</Badge> |
|
|
)} |
|
|
</div> |
|
|
<p className="text-slate-500 mt-1"> |
|
|
{integration.description} |
|
|
</p> |
|
|
|
|
|
{integration.connected && ( |
|
|
<div className="flex items-center gap-4 mt-3"> |
|
|
<div className="flex items-center gap-2 text-sm"> |
|
|
<Key className="w-4 h-4 text-slate-400" /> |
|
|
<span className="text-slate-600">{integration.account}</span> |
|
|
</div> |
|
|
<div className="flex items-center gap-2 text-sm"> |
|
|
<RefreshCw className="w-4 h-4 text-slate-400" /> |
|
|
<span className="text-slate-500">Synced {integration.lastSync}</span> |
|
|
</div> |
|
|
</div> |
|
|
)} |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
{/* Features */} |
|
|
<div className="mt-6"> |
|
|
<p className="text-sm font-medium text-slate-700 mb-3">Features</p> |
|
|
<div className="grid sm:grid-cols-2 gap-2"> |
|
|
{integration.features.map((feature, idx) => ( |
|
|
<div key={idx} className="flex items-center gap-2 text-sm text-slate-600"> |
|
|
<Check className="w-4 h-4 text-emerald-500 shrink-0" /> |
|
|
<span>{feature}</span> |
|
|
</div> |
|
|
))} |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
{/* Right Section - Actions */} |
|
|
<div className="lg:w-64 p-6 bg-slate-50 border-t lg:border-t-0 lg:border-l border-slate-100 flex flex-col justify-center"> |
|
|
{integration.connected ? ( |
|
|
<div className="space-y-4"> |
|
|
<Dialog> |
|
|
<DialogTrigger asChild> |
|
|
<Button variant="outline" className="w-full gap-2"> |
|
|
<Settings className="w-4 h-4" /> |
|
|
Settings |
|
|
</Button> |
|
|
</DialogTrigger> |
|
|
<DialogContent> |
|
|
<DialogHeader> |
|
|
<DialogTitle className="flex items-center gap-3"> |
|
|
<div className={`w-10 h-10 rounded-lg ${integration.bgColor} flex items-center justify-center`}> |
|
|
<integration.icon className="w-5 h-5 text-white" /> |
|
|
</div> |
|
|
{integration.name} Settings |
|
|
</DialogTitle> |
|
|
<DialogDescription> |
|
|
Configure your {integration.name} integration preferences |
|
|
</DialogDescription> |
|
|
</DialogHeader> |
|
|
<div className="space-y-6 pt-4"> |
|
|
<div className="flex items-center justify-between"> |
|
|
<div> |
|
|
<Label className="text-sm font-medium">Auto-post scheduled content</Label> |
|
|
<p className="text-xs text-slate-500 mt-0.5"> |
|
|
Automatically publish posts at scheduled times |
|
|
</p> |
|
|
</div> |
|
|
<Switch checked={autoPost} onCheckedChange={setAutoPost} /> |
|
|
</div> |
|
|
<Separator /> |
|
|
<div className="flex items-center justify-between"> |
|
|
<div> |
|
|
<Label className="text-sm font-medium">Post notifications</Label> |
|
|
<p className="text-xs text-slate-500 mt-0.5"> |
|
|
Get notified when posts are published |
|
|
</p> |
|
|
</div> |
|
|
<Switch checked={notifications} onCheckedChange={setNotifications} /> |
|
|
</div> |
|
|
<Separator /> |
|
|
<div> |
|
|
<Label className="text-sm font-medium">Connected Account</Label> |
|
|
<div className="flex items-center gap-3 mt-2 p-3 rounded-lg bg-slate-50"> |
|
|
<div className={`w-8 h-8 rounded-lg ${integration.bgColor} flex items-center justify-center`}> |
|
|
<integration.icon className="w-4 h-4 text-white" /> |
|
|
</div> |
|
|
<div className="flex-1"> |
|
|
<p className="text-sm font-medium text-slate-700">{integration.account}</p> |
|
|
<p className="text-xs text-slate-500">Connected</p> |
|
|
</div> |
|
|
<Button variant="ghost" size="sm" className="text-red-600 hover:text-red-700 hover:bg-red-50"> |
|
|
Disconnect |
|
|
</Button> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</DialogContent> |
|
|
</Dialog> |
|
|
<Button variant="ghost" className="w-full gap-2 text-red-600 hover:text-red-700 hover:bg-red-50"> |
|
|
<X className="w-4 h-4" /> |
|
|
Disconnect |
|
|
</Button> |
|
|
</div> |
|
|
) : ( |
|
|
<div className="space-y-4"> |
|
|
<Dialog> |
|
|
<DialogTrigger asChild> |
|
|
<Button className={`w-full gap-2 ${ |
|
|
integration.id === 'linkedin' |
|
|
? 'bg-[#0A66C2] hover:bg-[#004182]' |
|
|
: 'bg-gradient-to-r from-[#00C4CC] to-[#7B2FF7] hover:opacity-90' |
|
|
}`}> |
|
|
<Link2 className="w-4 h-4" /> |
|
|
Connect {integration.name} |
|
|
</Button> |
|
|
</DialogTrigger> |
|
|
<DialogContent> |
|
|
<DialogHeader> |
|
|
<DialogTitle className="flex items-center gap-3"> |
|
|
<div className={`w-10 h-10 rounded-lg ${integration.bgColor} flex items-center justify-center`}> |
|
|
<integration.icon className="w-5 h-5 text-white" /> |
|
|
</div> |
|
|
Connect to {integration.name} |
|
|
</DialogTitle> |
|
|
<DialogDescription> |
|
|
Authorize access to your {integration.name} account |
|
|
</DialogDescription> |
|
|
</DialogHeader> |
|
|
<div className="space-y-6 pt-4"> |
|
|
<div className="p-4 rounded-xl bg-slate-50 border border-slate-100"> |
|
|
<div className="flex items-start gap-3"> |
|
|
<Shield className="w-5 h-5 text-blue-600 mt-0.5" /> |
|
|
<div> |
|
|
<p className="text-sm font-medium text-slate-700">Secure Connection</p> |
|
|
<p className="text-xs text-slate-500 mt-1"> |
|
|
Your credentials are encrypted and never stored. We only request necessary permissions. |
|
|
</p> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<Label className="text-sm font-medium">Permissions Requested</Label> |
|
|
<div className="mt-2 space-y-2"> |
|
|
{integration.id === 'linkedin' ? ( |
|
|
<> |
|
|
<div className="flex items-center gap-2 text-sm text-slate-600"> |
|
|
<Check className="w-4 h-4 text-emerald-500" /> |
|
|
Read and write posts on your behalf |
|
|
</div> |
|
|
<div className="flex items-center gap-2 text-sm text-slate-600"> |
|
|
<Check className="w-4 h-4 text-emerald-500" /> |
|
|
Schedule posts for future publishing |
|
|
</div> |
|
|
<div className="flex items-center gap-2 text-sm text-slate-600"> |
|
|
<Check className="w-4 h-4 text-emerald-500" /> |
|
|
Access post analytics and insights |
|
|
</div> |
|
|
</> |
|
|
) : ( |
|
|
<> |
|
|
<div className="flex items-center gap-2 text-sm text-slate-600"> |
|
|
<Check className="w-4 h-4 text-emerald-500" /> |
|
|
View your Canva designs |
|
|
</div> |
|
|
<div className="flex items-center gap-2 text-sm text-slate-600"> |
|
|
<Check className="w-4 h-4 text-emerald-500" /> |
|
|
Download designs as images |
|
|
</div> |
|
|
<div className="flex items-center gap-2 text-sm text-slate-600"> |
|
|
<Check className="w-4 h-4 text-emerald-500" /> |
|
|
Access brand kit assets |
|
|
</div> |
|
|
</> |
|
|
)} |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<Button className={`w-full gap-2 ${ |
|
|
integration.id === 'linkedin' |
|
|
? 'bg-[#0A66C2] hover:bg-[#004182]' |
|
|
: 'bg-gradient-to-r from-[#00C4CC] to-[#7B2FF7] hover:opacity-90' |
|
|
}`}> |
|
|
Continue with {integration.name} |
|
|
<ExternalLink className="w-4 h-4" /> |
|
|
</Button> |
|
|
</div> |
|
|
</DialogContent> |
|
|
</Dialog> |
|
|
<p className="text-xs text-center text-slate-500"> |
|
|
You'll be redirected to {integration.name} to authorize |
|
|
</p> |
|
|
</div> |
|
|
)} |
|
|
</div> |
|
|
</div> |
|
|
</CardContent> |
|
|
</Card> |
|
|
</motion.div> |
|
|
))} |
|
|
</div> |
|
|
|
|
|
{} |
|
|
<motion.div |
|
|
initial={{ opacity: 0, y: 20 }} |
|
|
animate={{ opacity: 1, y: 0 }} |
|
|
transition={{ delay: 0.3 }} |
|
|
className="mt-8" |
|
|
> |
|
|
<Card className="border-0 shadow-lg shadow-slate-200/50"> |
|
|
<CardHeader> |
|
|
<CardTitle className="text-lg font-semibold flex items-center gap-2"> |
|
|
<Key className="w-5 h-5 text-amber-500" /> |
|
|
API Configuration |
|
|
</CardTitle> |
|
|
<CardDescription> |
|
|
For advanced users who want to configure custom API settings |
|
|
</CardDescription> |
|
|
</CardHeader> |
|
|
<CardContent className="space-y-4"> |
|
|
<div className="grid md:grid-cols-2 gap-4"> |
|
|
<div> |
|
|
<Label className="text-sm text-slate-600">LinkedIn Client ID</Label> |
|
|
<Input |
|
|
className="mt-1.5" |
|
|
placeholder="Enter your LinkedIn Client ID" |
|
|
type="password" |
|
|
defaultValue="••••••••••••••••" |
|
|
/> |
|
|
</div> |
|
|
<div> |
|
|
<Label className="text-sm text-slate-600">LinkedIn Client Secret</Label> |
|
|
<Input |
|
|
className="mt-1.5" |
|
|
placeholder="Enter your LinkedIn Client Secret" |
|
|
type="password" |
|
|
defaultValue="••••••••••••••••" |
|
|
/> |
|
|
</div> |
|
|
<div> |
|
|
<Label className="text-sm text-slate-600">Canva API Key</Label> |
|
|
<Input |
|
|
className="mt-1.5" |
|
|
placeholder="Enter your Canva API Key" |
|
|
type="password" |
|
|
/> |
|
|
</div> |
|
|
<div> |
|
|
<Label className="text-sm text-slate-600">Webhook URL</Label> |
|
|
<Input |
|
|
className="mt-1.5" |
|
|
placeholder="https://your-webhook-url.com" |
|
|
/> |
|
|
</div> |
|
|
</div> |
|
|
<div className="flex justify-end"> |
|
|
<Button variant="outline" className="gap-2"> |
|
|
<Save className="w-4 h-4" /> |
|
|
Save Configuration |
|
|
</Button> |
|
|
</div> |
|
|
</CardContent> |
|
|
</Card> |
|
|
</motion.div> |
|
|
</div> |
|
|
</div> |
|
|
); |
|
|
} |
|
|
|
|
|
|