Download frontend/src/components/Layout.tsx from omaib/MuSProt: direct link, hf CLI and curl.
- Browser
- Download file 4.73 kB
-
https://huggingface.co/spaces/omaib/MuSProt/resolve/main/frontend/src/components/Layout.tsx
- Command line
-
hf download hf://spaces/omaib/MuSProt/frontend/src/components/Layout.tsx
-
curl -L -o Layout.tsx https://huggingface.co/spaces/omaib/MuSProt/resolve/main/frontend/src/components/Layout.tsx
4.73 kB
| import { useEffect, useState } from 'react'; | |
| import { Link, NavLink, useLocation } from 'react-router-dom'; | |
| import { Download, Menu, X } from 'lucide-react'; | |
| import { api } from '../lib/api'; | |
| import { SearchBox } from './SearchBox'; | |
| export function Logo({ size = 28 }: { size?: number }) { | |
| // Three conformational "states" joined by transitions. | |
| return ( | |
| <svg width={size} height={size} viewBox="0 0 32 32" aria-hidden className="logo-mark"> | |
| <rect width="32" height="32" rx="8" className="logo-mark__bg" /> | |
| <path d="M9 21.5 L16 10 L23 21.5" className="logo-mark__edge" /> | |
| <path d="M9 21.5 H23" className="logo-mark__edge logo-mark__edge--soft" /> | |
| <circle cx="16" cy="10" r="3.4" className="logo-mark__n1" /> | |
| <circle cx="9" cy="21.5" r="3.4" className="logo-mark__n2" /> | |
| <circle cx="23" cy="21.5" r="3.4" className="logo-mark__n3" /> | |
| </svg> | |
| ); | |
| } | |
| const NAV = [ | |
| { to: '/browse', label: 'Browse' }, | |
| { to: '/statistics', label: 'Statistics' }, | |
| { to: '/docs', label: 'Docs' }, | |
| ]; | |
| export function Header() { | |
| const location = useLocation(); | |
| const [open, setOpen] = useState(false); | |
| const isHome = location.pathname === '/'; | |
| useEffect(() => setOpen(false), [location.pathname, location.search]); | |
| return ( | |
| <header className={`site-header ${isHome ? 'site-header--home' : ''}`}> | |
| <div className="site-header__inner"> | |
| <Link to="/" className="brand" aria-label="MuSProt home"> | |
| <Logo /> | |
| <span className="brand__name">MuSProt</span> | |
| </Link> | |
| {!isHome && ( | |
| <div className="site-header__search"> | |
| <SearchBox placeholder="Search chain, entry, UniProt, function…" /> | |
| </div> | |
| )} | |
| <nav className="site-nav" aria-label="Main"> | |
| {NAV.map((n) => ( | |
| <NavLink key={n.to} to={n.to} className={({ isActive }) => `site-nav__link ${isActive ? 'is-active' : ''}`}> | |
| {n.label} | |
| </NavLink> | |
| ))} | |
| <a href={api.downloadUrl} className="btn btn--primary btn--sm"> | |
| <Download aria-hidden /> Download | |
| </a> | |
| </nav> | |
| <button | |
| type="button" | |
| className="menu-toggle" | |
| aria-label="Menu" | |
| aria-expanded={open} | |
| onClick={() => setOpen((o) => !o)} | |
| > | |
| {open ? <X aria-hidden /> : <Menu aria-hidden />} | |
| </button> | |
| </div> | |
| {open && ( | |
| <div className="mobile-nav"> | |
| {!isHome && <SearchBox placeholder="Search MuSProt…" />} | |
| {NAV.map((n) => ( | |
| <NavLink key={n.to} to={n.to} className="mobile-nav__link"> | |
| {n.label} | |
| </NavLink> | |
| ))} | |
| <a href={api.downloadUrl} className="btn btn--primary"> | |
| <Download aria-hidden /> Download MuSProt.db | |
| </a> | |
| </div> | |
| )} | |
| </header> | |
| ); | |
| } | |
| export function Footer() { | |
| return ( | |
| <footer className="site-footer"> | |
| <div className="site-footer__inner"> | |
| <div className="site-footer__brand"> | |
| <Link to="/" className="brand"> | |
| <Logo size={24} /> | |
| <span className="brand__name">MuSProt</span> | |
| </Link> | |
| <p> | |
| A million-scale database of experimentally observed conformational states and state transitions of proteins, | |
| built from the Protein Data Bank. | |
| </p> | |
| </div> | |
| <div className="site-footer__cols"> | |
| <div> | |
| <h3>Explore</h3> | |
| <Link to="/browse">Browse sequences</Link> | |
| <Link to="/browse?min_states=5">Highly multistate</Link> | |
| <Link to="/chain/3vgk/A">Example chain</Link> | |
| </div> | |
| <div> | |
| <h3>Data</h3> | |
| <Link to="/docs">Documentation</Link> | |
| <a href={api.downloadUrl}>Download SQLite</a> | |
| <a href="/api/docs" target="_blank" rel="noopener noreferrer"> | |
| REST API | |
| </a> | |
| </div> | |
| <div> | |
| <h3>Sources</h3> | |
| <a href="https://www.rcsb.org" target="_blank" rel="noopener noreferrer"> | |
| RCSB PDB | |
| </a> | |
| <a href="https://www.uniprot.org" target="_blank" rel="noopener noreferrer"> | |
| UniProt | |
| </a> | |
| <a href="https://www.cathdb.info" target="_blank" rel="noopener noreferrer"> | |
| CATH | |
| </a> | |
| </div> | |
| </div> | |
| </div> | |
| <div className="site-footer__base"> | |
| <span>MuSProt · Multistate Protein Database</span> | |
| <a href="https://huggingface.co/spaces/omaib/MuSProt" target="_blank" rel="noopener noreferrer"> | |
| Hosted on Hugging Face | |
| </a> | |
| </div> | |
| </footer> | |
| ); | |
| } | |