File size: 3,575 Bytes
5a0e691
 
2f67ecf
5a0e691
 
2f67ecf
5a0e691
 
9a28cd0
5a0e691
 
973dd4c
9a28cd0
5a0e691
2a12412
5a0e691
 
2a12412
5a0e691
2a12412
 
5a0e691
 
2a12412
5a0e691
 
 
 
 
 
 
 
2a12412
 
5a0e691
 
 
 
2a12412
 
5a0e691
 
 
 
 
 
2a12412
 
5a0e691
 
 
 
 
 
2a12412
 
 
5a0e691
 
 
 
2a12412
 
5a0e691
 
2a12412
5a0e691
2a12412
5a0e691
 
 
 
 
2f67ecf
5a0e691
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
'use client';

import { motion } from 'framer-motion';
import { ExternalLink } from 'lucide-react';
import type { UniprotSummary } from '@/types/pipeline';
import { fadeUp, cardHover } from '@/lib/animations';

interface UniprotPanelProps {
  data: UniprotSummary | null;
}

export function UniprotPanel({ data }: UniprotPanelProps) {
  if (!data) return null;
  return (
    <motion.div variants={fadeUp} whileHover={cardHover} className="glass-card p-6">
      <div className="flex items-start justify-between mb-4">
        <div>
          <h3 className="font-medium text-text-primary">{data.full_name}</h3>
          <div className="flex items-center gap-3 mt-1">
            <span className="font-mono text-xs bg-accent-cyan/10 text-accent-cyan px-2 py-0.5 rounded">{data.accession}</span>
            <span className="text-sm text-text-secondary">{data.organism}</span>
          </div>
        </div>
        <a href={`https://www.uniprot.org/uniprotkb/${data.accession}`} target="_blank" rel="noopener noreferrer" className="text-sm text-accent-cyan hover:text-accent-cyan/80 transition flex items-center gap-1">
          UniProt <ExternalLink className="w-3.5 h-3.5" />
        </a>
      </div>

      <div className="grid md:grid-cols-2 gap-4">
        <div>
          {data.gene_names?.length > 0 && (
            <div className="mb-3">
              <h4 className="text-xs font-semibold text-text-muted uppercase tracking-wider mb-1">Gene</h4>
              <div className="flex flex-wrap gap-1">{data.gene_names.map(g => <span key={g} className="text-sm bg-surface-1 px-2 py-0.5 rounded font-mono text-text-secondary">{g}</span>)}</div>
            </div>
          )}
          {data.subcellular_locations?.length > 0 && (
            <div>
              <h4 className="text-xs font-semibold text-text-muted uppercase tracking-wider mb-1">Location</h4>
              <div className="flex flex-wrap gap-1">{data.subcellular_locations.map(loc => <span key={loc} className="text-sm bg-accent-purple/10 text-accent-purple px-2 py-0.5 rounded">{loc}</span>)}</div>
            </div>
          )}
        </div>
        <div>
          {data.keywords?.length > 0 && (
            <div>
              <h4 className="text-xs font-semibold text-text-muted uppercase tracking-wider mb-1">Keywords</h4>
              <div className="flex flex-wrap gap-1">{data.keywords.map(kw => <span key={kw} className="text-xs bg-surface-1 text-text-muted px-2 py-0.5 rounded">{kw}</span>)}</div>
            </div>
          )}
        </div>
      </div>

      {data.functions?.length > 0 && (
        <div className="mt-4 pt-4 border-t border-glass-border">
          <h4 className="text-xs font-semibold text-text-muted uppercase tracking-wider mb-2">Function</h4>
          {data.functions.map((f, fi) => <p key={fi} className="text-sm text-text-secondary leading-relaxed mb-1">{f}</p>)}
        </div>
      )}

      {data.features?.length > 0 && (
        <div className="mt-4 pt-4 border-t border-glass-border">
          <h4 className="text-xs font-semibold text-text-muted uppercase tracking-wider mb-2">Active Sites & Features</h4>
          <div className="space-y-1">
            {data.features.map((f, fi) => (
              <div key={fi} className="text-sm text-text-secondary">
                <span className="font-medium">{f.type}:</span> {f.description}
                {(f.begin || f.end) && <span className="text-text-muted"> ({f.begin}–{f.end})</span>}
              </div>
            ))}
          </div>
        </div>
      )}
    </motion.div>
  );
}