From f7b58be0888c48a45b601aa2810e533f2da91fe0 Mon Sep 17 00:00:00 2001 From: raiden9420 Date: Sun, 22 Mar 2026 17:52:01 +0530 Subject: [PATCH 1/2] chore: ignore agent metadata and reports; update UI components --- .gitignore | 13 +- Team_T8_report_20260318.pdf | Bin 14466 -> 0 bytes frontend/src/App.jsx | 118 ++++++++---------- frontend/src/components/MolViewer.jsx | 9 +- frontend/src/components/PldtMetrics.jsx | 4 +- frontend/src/components/ProteinMetrics.jsx | 6 +- frontend/src/components/SequenceInput.jsx | 35 ++++-- frontend/src/components/Sidebar.jsx | 11 +- frontend/src/components/TopBar.jsx | 6 +- frontend/src/index.css | 134 ++++++++++++--------- skills-lock.json | 110 +++++++++++++++++ 11 files changed, 295 insertions(+), 151 deletions(-) delete mode 100644 Team_T8_report_20260318.pdf create mode 100644 skills-lock.json diff --git a/.gitignore b/.gitignore index 4c4563d..e6b98d0 100644 --- a/.gitignore +++ b/.gitignore @@ -100,9 +100,10 @@ TESTSPRITE_GUIDE.md # AI & LLM Agents .gemini/ -# Testing Caches -.pytest_cache/ -.mypy_cache/ - -# Un-ignore the frontend lib folder which was caught by the Python lib/ rule -!frontend/src/lib/ \ No newline at end of file +# AI Agent Reports & Metadata +.agents/ +impeccable.md +.impeccable.md +audit_report.md +critique_report.md +Team_T8_report_*.pdf \ No newline at end of file diff --git a/Team_T8_report_20260318.pdf b/Team_T8_report_20260318.pdf deleted file mode 100644 index d73f688aab3932e076cf1458c2fb49498dc870aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14466 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 t?Qi+Tuq3}%_Uq -
+
-
-
-
-

Overview

-

Protein Structure

-
-
-
- 🕐 - 24H - 📅 - - {new Date().toLocaleDateString('en-US', { - day: 'numeric', - month: 'long', - year: 'numeric', - })} - -
- -
+
+
+
+ + +
-
-
-
- - - +
+
+
+
+

Overview

+

Protein Structure

+
+
+
+ 🕐 + 24H + 📅 + + {new Date().toLocaleDateString('en-US', { + day: 'numeric', + month: 'long', + year: 'numeric', + })} + +
+
- -
handlePredict()} + onPredict={handlePredict} status={status} /> @@ -392,7 +382,6 @@ export default function App() { />
- )} {/* ========== DISCOVERY VIEW ========== */} @@ -425,35 +414,33 @@ export default function App() { {/* ========== ANALYSIS VIEW ========== */} {view === 'analysis' && ( - <> -
-
-
-

{selectedProtein?.proteinName || 'Analyzing Protein…'}

-

- {selectedProtein - ? `${selectedProtein.accession} · ${selectedProtein.organism}` - : 'Fetching protein data…'} -

-
-
- -
+
+
+
+ + +
-
-
-
- - - +
+
+
+
+

{selectedProtein?.proteinName || 'Analyzing Protein…'}

+

+ {selectedProtein + ? `${selectedProtein.accession} · ${selectedProtein.organism}` + : 'Fetching protein data…'} +

+
+
+ +
- -
@@ -474,9 +461,8 @@ export default function App() {
- )} -
+
diff --git a/frontend/src/components/MolViewer.jsx b/frontend/src/components/MolViewer.jsx index 1c741bb..fe5c0d4 100644 --- a/frontend/src/components/MolViewer.jsx +++ b/frontend/src/components/MolViewer.jsx @@ -1,4 +1,4 @@ -import { useEffect, useRef, useState, useCallback } from 'react'; +import { useEffect, useRef, useState, useCallback, memo } from 'react'; const VIZ_STYLES = [ { key: 'cartoon', label: 'Cartoon', icon: '🎨' }, @@ -7,7 +7,7 @@ const VIZ_STYLES = [ { key: 'surface', label: 'Surface', icon: '◐' }, ]; -export default function MolViewer({ pdbData, status }) { +export default memo(function MolViewer({ pdbData, status }) { const containerRef = useRef(null); const viewerRef = useRef(null); const [vizStyle, setVizStyle] = useState('cartoon'); @@ -117,6 +117,7 @@ export default function MolViewer({ pdbData, status }) { key={s.key} className={`mol-viewer__style-btn${vizStyle === s.key ? ' mol-viewer__style-btn--active' : ''}`} title={s.label} + aria-label={s.label} onClick={() => { setVizStyle(s.key); applyStyle(s.key); @@ -131,6 +132,7 @@ export default function MolViewer({ pdbData, status }) { - @@ -71,8 +82,8 @@ export default function SequenceInput({ sequence, setSequence, onPredict, status id="sequence-textarea" className="sequence-input__textarea" placeholder="Paste your amino-acid sequence here (single letter codes: A, C, D, E, F, G, H, I, K, L, M, N, P, Q, R, S, T, V, W, Y)…" - value={sequence} - onChange={(e) => setSequence(e.target.value.toUpperCase().replace(/[^A-Z]/g, ''))} + value={localSeq} + onChange={(e) => setLocalSeq(e.target.value.toUpperCase().replace(/[^A-Z]/g, ''))} spellCheck={false} style={hasInvalid ? { borderColor: 'var(--warning)' } : undefined} /> @@ -104,7 +115,7 @@ export default function SequenceInput({ sequence, setSequence, onPredict, status - - - @@ -130,7 +131,7 @@ export default function TopBar({ )} -