Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: make ML Challenge Page mobile friendly #1141

Merged
merged 4 commits into from
Sep 21, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,39 +1,30 @@
import { MenuDropdown } from 'app/components/MenuDropdown'
import { MenuItemHeader } from 'app/components/MenuItemHeader'
import { MenuItemLink } from 'app/components/MenuItemLink'
import { i18n } from 'app/i18n'
import { useI18n } from 'app/hooks/useI18n'

const REPO = 'https://github.com/chanzuckerberg/cryoet-data-portal'
import { ABOUT_LINKS, HELP_AND_REPORT_LINKS } from './constants'

export function AboutAndHelpDropdown({ className }: { className?: string }) {
return (
<MenuDropdown className={className} title={i18n.aboutAndHelp}>
<MenuItemHeader>{i18n.about}</MenuItemHeader>

<MenuItemLink to="/faq">{i18n.faq}</MenuItemLink>
{/* <MenuItemLink to="/license">{i18n.license}</MenuItemLink> */}
<MenuItemLink to="/privacy">{i18n.privacyPolicy}</MenuItemLink>
{/* <MenuItemLink to="/terms" divider> */}
<MenuItemLink to="/data-submission-policy">
{i18n.dataSubmissionPolicy}
</MenuItemLink>
{/* <MenuItemLink to="/terms" divider>
{i18n.termsOfUse}
</MenuItemLink> */}
const { t } = useI18n()

<MenuItemHeader>{i18n.helpAndReport}</MenuItemHeader>
return (
<MenuDropdown className={className} title={t('aboutAndHelp')}>
<MenuItemHeader>{t('about')}</MenuItemHeader>

<MenuItemLink to="https://chanzuckerberg.github.io/cryoet-data-portal">
{i18n.goToDocs}
</MenuItemLink>
{ABOUT_LINKS.map(({ label, link }) => (
<MenuItemLink key={label} to={link}>
{t(label)}
</MenuItemLink>
))}

<MenuItemLink
to={`${REPO}/issues/new?assignees=&labels=bug&projects=&template=bug.md&title=`}
>
{i18n.reportIssueOnGithub}
</MenuItemLink>
<MenuItemHeader>{t('helpAndReport')}</MenuItemHeader>

<MenuItemLink to={`${REPO}/discussions`}>{i18n.askOnGitHub}</MenuItemLink>
{HELP_AND_REPORT_LINKS.map(({ label, link }) => (
<MenuItemLink key={label} to={link}>
{t(label)}
</MenuItemLink>
))}
</MenuDropdown>
)
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import { Link } from 'app/components/Link'
import { i18n } from 'app/i18n'
import { SiteLinks } from 'app/constants/siteLinks'
import { useI18n } from 'app/hooks/useI18n'

export function CryoETHomeLink() {
const { t } = useI18n()

return (
<div className="flex items-center gap-sds-s text-sds-gray-white">
<Link className="text-sds-header-m font-semibold ml-2 " to="/">
{i18n.title}
<Link
className="text-sds-header-m font-semibold ml-2 whitespace-nowrap"
to={SiteLinks.HOME}
>
{t('title')}
</Link>
<div className="px-sds-xs py-sds-xxxs bg-sds-info-400 rounded-sds-m text-sds-body-xxxs">
{i18n.beta}
{t('beta')}
</div>
</div>
)
Expand Down
23 changes: 11 additions & 12 deletions frontend/packages/data-portal/app/components/Layout/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,17 +76,16 @@ export function Footer() {
)

return (
<footer className="bg-sds-gray-black min-h-[213px] p-sds-xxl flex flex-col flex-shrink-0">
<div className="flex items-center flex-wrap flex-col sm:flex-row sm:gap-y-sds-xxl">
<footer className="bg-sds-gray-black min-h-[213px] pt-[41px] pb-sds-xxl px-sds-xl screen-716:px-sds-xxl flex flex-col flex-shrink-0">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be done later, but if 716 is the breakpoint we're going to settle on for phones it might make sense to add it to our tailwind config

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I just realized this is the alias 😆. Maybe we should give them better semantics like "phone", "desktop" or whatever, but that's not really relevant to this PR

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we've used this pattern in the past for the napari hub because our breakpoints didn't really have good semantics. I think when SDS officially defines semantic breakpoints for their framework, then we can start using that

I'm also curious from @Janeece @kev-zunshiwang on this, we could defer to SDS or figure out semantic breakpoints for the data portal, but I imagine it would take time to holistically determine the right breakpoints and I know mobile hasn't been a priority up until now 🤔

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@codemonkey800 SDS has had breakpoints on its backlog for a long time -- im not sure if that work has been completed (Connor was scoping it, last I heard). We'd want to defer to SDS when they have defined them.

Agreed, mobile has not been generally considered a priority, ML challenge page was a special case because of how the page is promoted.

<div className="flex items-center flex-wrap flex-col screen-716:flex-row gap-y-sds-xl screen-716:gap-y-sds-xxl">
<CryoETHomeLink />

<div className="flex-grow" />
<div className="flex-grow hidden screen-716:block" />

<div
className={cns(
'mt-sds-xxl sm:mt-0',
'flex flex-col sm:flex-row',
'items-center gap-sds-xxl',
'flex flex-col screen-716:flex-row',
'items-center gap-sds-m screen-716:gap-sds-xxl',
'text-sds-body-s font-semibold',
)}
>
Expand All @@ -102,14 +101,14 @@ export function Footer() {
</div>
</div>

<div className="flex items-center mt-[70px] text-sds-body-s flex-col sm:flex-row gap-y-sds-xxl">
<div className="hidden sm:block">{legalLinks}</div>
<div className="sm:hidden">{cziLinks}</div>
<div className="flex items-center mt-[36px] screen-716:mt-[70px] text-sds-body-s flex-col screen-716:flex-row gap-y-sds-l screen-716:gap-y-sds-xxl">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<div className="flex items-center mt-[36px] screen-716:mt-[70px] text-sds-body-s flex-col screen-716:flex-row gap-y-sds-l screen-716:gap-y-sds-xxl">
<div className="flex items-center mt-9 screen-716:mt-[70px] text-sds-body-s flex-col screen-716:flex-row gap-y-sds-l screen-716:gap-y-sds-xxl">
image

<div className="hidden screen-716:block">{legalLinks}</div>
<div className="screen-716:hidden">{cziLinks}</div>

<div className="flex-grow" />
<div className="flex-grow hidden screen-716:block" />

<div className="sm:hidden">{legalLinks}</div>
<div className="hidden sm:block">{cziLinks}</div>
<div className="screen-716:hidden">{legalLinks}</div>
<div className="hidden screen-716:block">{cziLinks}</div>
</div>
</footer>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { ButtonIcon } from '@czi-sds/components'

import { Link } from 'app/components/Link'
import { useI18n } from 'app/hooks/useI18n'
import { I18nKeys } from 'app/types/i18n'

import {
ABOUT_LINKS,
HELP_AND_REPORT_LINKS,
NavLink,
TOOLS_LINKS,
TOP_LEVEL_LINKS,
} from './constants'
import { CryoETHomeLink } from './CryoETHomeLink'

function SubMenu({ title, links }: { title: I18nKeys; links: NavLink[] }) {
const { t } = useI18n()

return (
<div className="border-t border-sds-gray-500 pt-sds-l flex flex-col gap-sds-l">
<p className="text-sds-caps-xxs leading-sds-caps-xxs font-semibold uppercase text-sds-gray-400">
{t(title)}
</p>
<div className="flex flex-col gap-sds-m">
{links.map(({ label, link }) => (
<Link
key={label}
to={link}
className="text-sds-header-m leading-sds-header-m font-semibold text-sds-gray-300"
>
{t(label)}
</Link>
))}
</div>
</div>
)
}

export function MobileNavigationMenu({ onClose }: { onClose: () => void }) {
const { t } = useI18n()

return (
<nav className="fixed z-30 top-0 bottom-0 right-0 left-0 bg-black screen-716:hidden px-sds-xl overflow-y-scroll">
<div className="flex justify-between py-sds-m items-center">
<CryoETHomeLink />
<ButtonIcon
sdsIcon="xMark"
sdsSize="large"
sdsType="secondary"
classes={{
root: '!text-sds-gray-white',
}}
onClick={onClose}
/>
</div>
<div className="flex flex-col py-sds-l gap-sds-xl">
{TOP_LEVEL_LINKS.map(({ label, link }) => (
<Link
key={label}
to={link}
className="text-sds-header-m leading-sds-header-m font-semibold text-sds-gray-300"
>
{t(label)}
</Link>
))}
<SubMenu title="tools" links={TOOLS_LINKS} />
<SubMenu title="about" links={ABOUT_LINKS} />
<SubMenu title="helpAndReport" links={HELP_AND_REPORT_LINKS} />
</div>
</nav>
)
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import { MenuDropdown } from 'app/components/MenuDropdown'
import { MenuItemLink } from 'app/components/MenuItemLink'
import { i18n } from 'app/i18n'
import { useI18n } from 'app/hooks/useI18n'

import { TOOLS_LINKS } from './constants'

export function ToolsDropdown({ className }: { className?: string }) {
const { t } = useI18n()
return (
<MenuDropdown className={className} title={i18n.tools}>
<MenuItemLink to="https://chanzuckerberg.github.io/cryoet-data-portal/python-api.html">
{i18n.api}
</MenuItemLink>

<MenuItemLink to="https://chanzuckerberg.github.io/cryoet-data-portal/cryoet_data_portal_docsite_napari.html">
{i18n.napariPlugin}
</MenuItemLink>
<MenuDropdown className={className} title={t('tools')}>
{TOOLS_LINKS.map(({ label, link }) => (
<MenuItemLink key={label} to={link}>
{t(label)}
</MenuItemLink>
))}
</MenuDropdown>
)
}
Original file line number Diff line number Diff line change
@@ -1,72 +1,76 @@
import { ButtonIcon } from '@czi-sds/components'
import { useLocation } from '@remix-run/react'
import { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'

import { Link } from 'app/components/Link'
import { I18nKeys } from 'app/types/i18n'
import { cns } from 'app/utils/cns'

import { AboutAndHelpDropdown } from './AboutAndHelpDropdown'
import { TOP_LEVEL_LINKS } from './constants'
import { CryoETHomeLink } from './CryoETHomeLink'
import { MobileNavigationMenu } from './MobileNavigationMenu'
import { ToolsDropdown } from './ToolsDropdown'

interface TopNavLink {
isActive(pathname: string): boolean
label: I18nKeys
link: string
}

const TOP_NAV_LINKS: TopNavLink[] = [
{
isActive: (pathname) =>
pathname.includes('/datasets') ||
pathname.includes('/runs') ||
pathname.includes('/depositions'),
label: 'browseData',
link: '/browse-data/datasets',
},

{
isActive: (pathname) => pathname === '/competition',
label: 'competition',
link: '/competition',
},
]

export function TopNavigation() {
const { pathname } = useLocation()
const { t } = useTranslation()

const [mobileMenuIsOpen, setMobileMenuOpen] = useState(false)

// force close mobile menu when navigating
useEffect(() => {
setMobileMenuOpen(false)
}, [pathname])

return (
<nav
className={cns(
'bg-sds-gray-black text-sds-gray-white',
'flex h-[45px] flex-shrink-0 items-center px-sds-xl',
'flex py-sds-m flex-shrink-0 items-center px-sds-xl',
'sticky top-0 z-30',
)}
>
<CryoETHomeLink />

{/* Add empty space to push content to right */}
<div className="flex-grow" />
<div className="basis-sds-xxl flex-grow screen-790:mr-sds-xxl" />

<div className="hidden screen-716:flex basis-auto flex-shrink-0">
{TOP_LEVEL_LINKS.map((link) => (
<Link
className={cns(
'text-sds-header-s leading-sds-header-s font-semibold mr-sds-xxl p-0',

{TOP_NAV_LINKS.map((link) => (
<Link
className={cns(
'text-sds-header-s leading-sds-header-s font-semibold mr-sds-xxl p-0',
link.isActive(pathname)
? 'text-sds-gray-white'
: 'text-sds-gray-400 hover:text-sds-gray-white',
)}
to={link.link}
key={link.link}
>
{t(link.label)}
</Link>
))}

link.isActive(pathname)
? 'text-sds-gray-white'
: 'text-sds-gray-400 hover:text-sds-gray-white',
)}
to={link.link}
key={link.link}
>
{t(link.label)}
</Link>
))}
<ToolsDropdown className="mr-sds-xxl text-sds-header-s" />
<AboutAndHelpDropdown className="screen-790:ml-sds-xxl text-sds-header-s" />
</div>

<ToolsDropdown className="mr-sds-xxl text-sds-header-s" />
<AboutAndHelpDropdown className="ml-sds-xxl text-sds-header-s" />
<ButtonIcon
className="screen-716:!hidden"
sdsIcon="linesHorizontal"
sdsType="tertiary"
sdsSize="large"
classes={{
root: '!text-sds-gray-400',
}}
onClick={() => setMobileMenuOpen(true)}
/>

{mobileMenuIsOpen && (
<MobileNavigationMenu onClose={() => setMobileMenuOpen(false)} />
)}
</nav>
)
}
Loading
Loading