| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- import React from 'react';
- import { useLanguage } from '../../contexts/LanguageContext';
- import { useNavigate } from 'react-router-dom';
- import { Search, Plus, MoreHorizontal, MessageSquare } from 'lucide-react';
- import { motion, AnimatePresence } from 'framer-motion';
- import { cn } from '../../src/utils/cn';
- // Mock data based on the provided design
- interface AgentMock {
- id: string;
- name: string;
- description: string;
- status: 'running' | 'stopped';
- updatedAt: string;
- iconEmoji: string;
- iconBgClass: string;
- path?: string;
- }
- const mockAgents: AgentMock[] = [
- {
- id: 'assessment',
- name: 'assessmentTitle',
- description: 'assessmentDesc',
- status: 'running',
- updatedAt: 'agent1Time',
- iconEmoji: '📋',
- iconBgClass: 'bg-blue-50',
- path: '/assessment'
- }
- ];
- export const AgentsView: React.FC = () => {
- const { t } = useLanguage();
- const navigate = useNavigate();
- return (
- <div className="flex flex-col h-full bg-[#f4f7fb] overflow-hidden">
- {/* Header Area */}
- <div className="px-8 pt-8 pb-6 flex items-start justify-between shrink-0">
- <div>
- <h1 className="text-[22px] font-bold text-slate-900 leading-tight">
- {t('agentTitle')}
- </h1>
- <p className="text-[14px] text-slate-500 mt-1">{t('agentDesc')}</p>
- </div>
- <div className="flex items-center gap-4">
- <div className="relative w-64">
- <Search className="absolute text-slate-400 left-3 top-1/2 -translate-y-1/2" size={16} />
- <input
- type="text"
- placeholder={t('searchAgent')}
- className="w-full h-10 pl-10 pr-4 bg-white border border-slate-200 rounded-lg focus:bg-white focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 outline-none transition-all text-sm font-medium"
- />
- </div>
- <button className="flex items-center gap-2 px-5 h-10 bg-blue-600 hover:bg-blue-700 text-white rounded-lg shadow-sm shadow-blue-100 transition-all font-semibold text-sm active:scale-95">
- <Plus size={18} />
- <span>{t('createAgent')}</span>
- </button>
- </div>
- </div>
- {/* Content Area */}
- <div className="px-8 pb-8 flex-1 overflow-y-auto">
- <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-6 max-w-[1600px] mx-auto">
- <AnimatePresence>
- {mockAgents.map((agent) => (
- <motion.div
- key={agent.id}
- layout
- initial={{ opacity: 0, y: 10 }}
- animate={{ opacity: 1, y: 0 }}
- className={cn(
- "bg-white rounded-2xl p-6 shadow-sm border border-slate-100 hover:shadow-md transition-all group flex flex-col h-[220px]",
- agent.path && "cursor-pointer hover:border-blue-200"
- )}
- onClick={() => {
- if (agent.path) {
- navigate(agent.path);
- }
- }}
- >
- {/* Top layer */}
- <div className="flex items-center justify-between mb-4">
- <div className={`w-12 h-12 flex items-center justify-center rounded-xl ${agent.iconBgClass} text-2xl`}>
- {agent.iconEmoji}
- </div>
- <div className="flex items-center gap-3">
- {/* Status Badge */}
- {agent.status === 'running' ? (
- <div className="px-2.5 py-1 text-[12px] font-semibold text-emerald-600 bg-emerald-50 rounded-full border border-emerald-100/50 flex flex-row items-center justify-center">
- {t('statusRunning')}
- </div>
- ) : (
- <div className="px-2.5 py-1 text-[12px] font-semibold text-slate-500 bg-slate-50 rounded-full border border-slate-100 flex flex-row items-center justify-center">
- {t('statusStopped')}
- </div>
- )}
- {/* Options button */}
- <button className="text-slate-400 hover:text-slate-600 transition-colors">
- <MoreHorizontal size={20} />
- </button>
- </div>
- </div>
- {/* Middle layer */}
- <div className="flex-1">
- <h3 className="font-bold text-slate-800 text-[17px] mb-2 leading-tight">
- {t(agent.name as any)}
- </h3>
- <p className="text-[13px] text-slate-500 leading-relaxed line-clamp-2">
- {t(agent.description as any)}
- </p>
- </div>
- {/* Bottom layer */}
- <div className="mt-4 pt-4 border-t border-slate-50 flex items-center justify-between">
- <span className="text-[12px] font-medium text-slate-400">
- {t('updatedAtPrefix')}{t(agent.updatedAt as any)}
- </span>
- <button
- onClick={(e) => {
- e.stopPropagation();
- if (agent.path) {
- navigate(agent.path);
- }
- }}
- className="flex items-center justify-center gap-1.5 px-3 py-1.5 text-blue-600 bg-blue-50 hover:bg-blue-100 rounded-lg transition-colors"
- >
- <MessageSquare size={14} className="text-blue-500" />
- <span className="text-[13px] font-bold">{t('btnChat')}</span>
- </button>
- </div>
- </motion.div>
- ))}
- </AnimatePresence>
- </div>
- </div>
- </div>
- );
- };
|