veza/apps/web/src/components/studio/ConnectivityView.tsx

192 lines
6.8 KiB
TypeScript

import React, { useState } from 'react';
import { Card } from '../ui/card';
import { Button } from '../ui/button';
import { Input } from '../ui/input';
import { Globe, Copy, Plus, Trash2, CheckCircle, Folder } from 'lucide-react';
import { useToast } from '../../context/ToastContext';
export const ConnectivityView: React.FC = () => {
const { addToast } = useToast();
// WebDAV State
const [webdavPass, setWebdavPass] = useState('****');
// Webhooks State
const [webhooks, setWebhooks] = useState([
{
id: '1',
url: 'https://api.myapp.com/hooks/veza',
events: ['file.upload', 'file.delete'],
},
]);
const [newHookUrl, setNewHookUrl] = useState('');
const generateWebdavPass = () => {
setWebdavPass(`wd-${Math.random().toString(36).substr(2, 10)}`);
addToast('New WebDAV password generated', 'success');
};
const addWebhook = () => {
if (!newHookUrl) return;
setWebhooks([
...webhooks,
{ id: Date.now().toString(), url: newHookUrl, events: ['file.upload'] },
]);
setNewHookUrl('');
addToast('Webhook endpoint added', 'success');
};
const copyToClipboard = (text: string) => {
navigator.clipboard.writeText(text);
addToast('Copied to clipboard');
};
return (
<div className="h-full flex flex-col gap-8 animate-fadeIn">
{/* WebDAV Mount Section */}
<Card variant="default">
<div className="flex items-start justify-between mb-6">
<div>
<h3 className="text-xl font-bold text-white flex items-center gap-2">
<Folder className="w-5 h-5 text-kodo-gold" /> Directory Mount
(WebDAV)
</h3>
<p className="text-sm text-kodo-content-dim mt-1">
Access your Cloud Studio files directly from your OS file explorer
or DAW.
</p>
</div>
<div className="bg-kodo-gold/10 text-kodo-gold px-3 py-1 rounded text-xs font-bold border border-kodo-gold/20">
PROTOCOL ACTIVE
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 bg-kodo-ink p-6 rounded-xl border border-kodo-steel">
<div>
<label className="block text-xs font-bold text-kodo-content-dim uppercase mb-2">
Server URL
</label>
<div className="flex gap-2">
<div className="flex-1 bg-kodo-graphite border border-kodo-steel rounded px-3 py-2 text-sm text-kodo-text-main font-mono truncate">
https://webdav.veza.io/u/cyber_producer
</div>
<Button
variant="ghost"
size="icon"
className="border border-kodo-steel"
onClick={() =>
copyToClipboard('https://webdav.veza.io/u/cyber_producer')
}
>
<Copy className="w-4 h-4" />
</Button>
</div>
</div>
<div>
<label className="block text-xs font-bold text-kodo-content-dim uppercase mb-2">
Username
</label>
<div className="flex gap-2">
<div className="flex-1 bg-kodo-graphite border border-kodo-steel rounded px-3 py-2 text-sm text-kodo-text-main font-mono">
cyber_producer
</div>
<Button
variant="ghost"
size="icon"
className="border border-kodo-steel"
onClick={() => copyToClipboard('cyber_producer')}
>
<Copy className="w-4 h-4" />
</Button>
</div>
</div>
<div className="md:col-span-2">
<label className="block text-xs font-bold text-kodo-content-dim uppercase mb-2">
Mount Password
</label>
<div className="flex gap-2">
<div className="flex-1 bg-kodo-graphite border border-kodo-steel rounded px-3 py-2 text-sm text-white font-mono tracking-widest">
{webdavPass}
</div>
<Button variant="secondary" onClick={generateWebdavPass}>
Generate New
</Button>
</div>
<p className="text-[10px] text-kodo-content-dim mt-2">
Use this specific password for mounting. Do not use your account
login password.
</p>
</div>
</div>
</Card>
{/* Webhooks Section */}
<Card variant="default">
<div className="flex items-start justify-between mb-6">
<div>
<h3 className="text-xl font-bold text-white flex items-center gap-2">
<Globe className="w-5 h-5 text-kodo-cyan" /> Storage Webhooks
</h3>
<p className="text-sm text-kodo-content-dim mt-1">
Trigger actions in external apps when files change.
</p>
</div>
</div>
<div className="space-y-4">
<div className="flex gap-2">
<Input
placeholder="https://api.your-app.com/hook"
value={newHookUrl}
onChange={(e) => setNewHookUrl(e.target.value)}
/>
<Button
variant="primary"
icon={<Plus className="w-4 h-4" />}
onClick={addWebhook}
>
Add
</Button>
</div>
<div className="space-y-2">
{webhooks.map((hook) => (
<div
key={hook.id}
className="flex items-center justify-between p-3 bg-kodo-ink rounded border border-kodo-steel"
>
<div className="flex-1 min-w-0 mr-4">
<div className="text-sm font-mono text-white truncate">
{hook.url}
</div>
<div className="text-xs text-kodo-content-dim mt-1 flex gap-2">
{hook.events.map((ev) => (
<span key={ev} className="bg-white/5 px-1 rounded">
{ev}
</span>
))}
</div>
</div>
<div className="flex items-center gap-2">
<div className="text-xs text-kodo-lime flex items-center gap-1">
<CheckCircle className="w-3 h-3" /> Active
</div>
<Button
variant="ghost"
size="icon"
className="text-kodo-red hover:bg-kodo-red/10"
onClick={() =>
setWebhooks(webhooks.filter((h) => h.id !== hook.id))
}
>
<Trash2 className="w-4 h-4" />
</Button>
</div>
</div>
))}
</div>
</div>
</Card>
</div>
);
};