From c7cbe265bf6c14b22e93a3bb8b7deda74d7e9c74 Mon Sep 17 00:00:00 2001 From: Caleb Jacob Date: Thu, 2 May 2024 09:10:11 -0600 Subject: [PATCH] AI Mobile Part (2 of 2) (#57) * Updating components to better support mobile devices for the short term * Adding overview wrapper page class * Remove extra mobile padding --- nexus/components/src/AI/Agent/AgentCard.jsx | 207 +++++++++++--------- nexus/components/src/AI/Navigation.jsx | 162 +++++++++++++++ nexus/components/src/AI/Nexus.jsx | 43 ++-- nexus/components/src/AI/Overview.jsx | 32 +-- 4 files changed, 308 insertions(+), 136 deletions(-) create mode 100644 nexus/components/src/AI/Navigation.jsx diff --git a/nexus/components/src/AI/Agent/AgentCard.jsx b/nexus/components/src/AI/Agent/AgentCard.jsx index be6a97e..28e3d95 100644 --- a/nexus/components/src/AI/Agent/AgentCard.jsx +++ b/nexus/components/src/AI/Agent/AgentCard.jsx @@ -8,62 +8,48 @@ const { namespace, entityType, schemaFile, returnTo } = props; const Card = styled.div` cursor: pointer; + display: flex; + flex-direction: column; + gap: 1rem; background-color: white; border-radius: 0.5rem; padding: 1.5rem; - gap: 1rem; height: 100%; - min-height: 12rem; transition: all 300ms; - box-shadow: - 0 1px 3px 0 rgb(0 0 0 / 0.1), - 0 1px 2px -1px rgb(0 0 0 / 0.1); + box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); &:hover { - box-shadow: - 0 4px 6px -1px rgb(0 0 0 / 0.1), - 0 2px 4px -2px rgb(0 0 0 / 0.1); + box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); } - img.logo { - width: 100%; + .logo { + width: 2.8rem; aspect-ratio: 1 / 1; border-radius: 50%; object-fit: cover; } - - h3, - p { - margin: 0; - } - - h3 { - font-size: 1.25rem; - font-weight: 600; - } - - p { - font-size: 1rem; - font-weight: 400; - } `; + const TagsWrapper = styled.div` padding: 4px; `; + const CardText = styled.div``; -const Prompt = styled.span` - color: grey; -`; + const PromptTooltip = styled.span` white-space: pre-line; `; + const Actions = styled.div` - padding-top: 16px; display: flex; align-items: center; gap: 2px; + margin-top: auto; + flex-wrap: wrap; + justify-content: space-between; `; + const sharedButtonStyles = ` display: inline-flex; align-items: center; @@ -91,6 +77,7 @@ const sharedButtonStyles = ` font-size: 16px; } `; + const Button = styled.button` ${sharedButtonStyles} color: ${(p) => (p.primary ? "#09342E" : "#11181C")} !important; @@ -103,6 +90,40 @@ const Button = styled.button` } `; +const Text = styled.p` + font: var(--${(p) => p.$size ?? "text-base"}); + font-weight: ${(p) => p.$fontWeight} !important; + color: var(--${(p) => p.$color ?? "sand12"}); + margin: 0; + word-break: break-word; + + @media (max-width: 900px) { + font: var(--${(p) => p.$mobileSize ?? p.$size ?? "text-base"}); + } +`; + +const LogoAndName = styled.div` + display: flex; + align-items: center; + gap: 1rem; +`; + +const Name = styled.div` + min-width: 0; + + * { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } +`; + +const Content = styled.div` + display: flex; + flex-direction: column; + gap: 0.5rem; +`; + const AgentCard = ({ item, editFunction }) => { const { accountId, name, displayName, prompt, logoUrl, tags } = item; const agentComponent = item.component @@ -135,37 +156,71 @@ const AgentCard = ({ item, editFunction }) => { return ( -
-
- agent logo - {tags && tags.length > 0 && ( - + + {imageUrl && agent logo} + + + {displayName} + + + by {accountId} + + + + + + {prompt ? prompt.substring(0, 50) : ""}... + + {tags && tags.length > 0 && ( + + + + )} + + + - - )} -
- - -

{displayName}

-

by {accountId}

- {prompt}, - trigger: ( - {prompt ? prompt.substring(0, 50) : ""}... - ), - }} - /> -
-
- - + + ), + }} + /> + + + + ), + }} + /> { src="${REPL_ACCOUNT}/widget/DIG.Button" props={{ onClick: () => editFunction(item), - iconLeft: editIcon, + icon: editIcon, variant: "secondary", fill: "ghost", size: "small", @@ -226,44 +281,6 @@ const AgentCard = ({ item, editFunction }) => { url: actionUrl, }} /> - - - - ), - }} - /> - - - - ), - }} - />
); diff --git a/nexus/components/src/AI/Navigation.jsx b/nexus/components/src/AI/Navigation.jsx new file mode 100644 index 0000000..1db8b38 --- /dev/null +++ b/nexus/components/src/AI/Navigation.jsx @@ -0,0 +1,162 @@ +const Navigation = styled.div` + width: 100%; + display: flex; + align-items: center; + gap: 1rem; + padding-bottom: 2rem; + border-bottom: 1px solid var(--sand4); + + @media (max-width: 600px) { + flex-direction: column; + align-items: flex-start; + } +`; + +const Actions = styled.div` + display: flex; + align-items: center; + gap: 1rem; + flex-wrap: wrap; +`; + +const Title = styled.h2` + font: var(--text-2xl); + font-weight: 600; + margin: 0; + margin-right: auto; + white-space: nowrap; + + @media (max-width: 600px) { + font: var(--text-xl); + font-weight: 600; + } +`; + +const MenuButton = styled.button` + all: unset; + padding: 0.5rem 0.75rem; + display: flex; + align-items: center; + gap: 0.75rem; + background: ${(p) => (p.$primary ? "var(--violet7)" : "var(--sand3)")}; + color: ${(p) => (p.$primary ? "#fff" : "var(--sand12)")}; + font-weight: 600; + border-radius: 4px; + box-shadow: 0 0 0 0px var(--violet4); + transition: all 200ms; + + i { + transition: all 200ms; + } + + i:first-child { + color: ${(p) => (p.$primary ? "var(--violet11)" : "var(--violet7)")}; + } + i:last-child { + color: ${(p) => (p.$primary ? "var(--violet10)" : "var(--sand9)")}; + } + + &:hover { + i:first-child { + color: ${(p) => (p.$primary ? "var(--violet12)" : "var(--violet8)")}; + } + i:last-child { + color: ${(p) => (p.$primary ? "var(--violet11)" : "var(--sand12)")}; + } + } + + &:focus { + background: var(--sand2); + box-shadow: 0 0 0 4px var(--violet4); + } + + @media (max-width: 500px) { + font: var(--text-s); + font-weight: 600; + } +`; + +const PopoverContent = styled("Popover.Content")` + background: #fff; + border-radius: 6px; + box-shadow: 0 0 40px rgba(0, 0, 0, 0.15); + z-index: 10000; + padding: 1rem; + max-width: 90vw; + width: 350px; + outline: none; + + ul { + list-style: none; + display: block; + margin: 0; + padding: 0; + } + + li { + display: block; + } + + a { + display: flex; + gap: 0.75rem; + align-items: center; + padding: 0.5rem; + font: var(--text-base); + color: var(--sand12); + outline: none; + text-decoration: none; + + &:hover, + &:focus { + text-decoration: underline; + } + } + + i { + color: var(--violet8); + } +`; + +const menuItems = props.items || []; +const activeItem = menuItems.find((item) => item.value === props.activeTab); + +return ( + + {props.title || ""} + + + + + + + Tags + + + + + {props.additionalContent} + + + + + + + {activeItem.name} + + + ), + items: menuItems.map((item) => ({ + name: item.name, + iconLeft: `${item.icon} ph-bold `, + onSelect: () => item.onSelect(item.value), + })), + }} + /> + + +); diff --git a/nexus/components/src/AI/Nexus.jsx b/nexus/components/src/AI/Nexus.jsx index b622f5c..3082042 100644 --- a/nexus/components/src/AI/Nexus.jsx +++ b/nexus/components/src/AI/Nexus.jsx @@ -1,15 +1,22 @@ const Wrapper = styled.div` - display: grid; - gap: 40px; - grid-template-columns: 244px 1.5fr; - align-items: start; - height: 100%; - - @media (max-width: 750px) { - display: flex; - flex-direction: column; - } + display: flex; + flex-direction: column; + gap: 2rem; + grid-template-columns: 200px 1fr; + width: 100%; + max-width: 960px; + margin: 0 auto; +`; + +const Section = styled.div` + width: 100%; +`; + +const Title = styled.h2` + font: var(--text-l); + font-weight: 600; `; + const { schema } = VM.require(`${REPL_ACCOUNT}/widget/AI.Schema.Nexus`); if (!schema) { return <>; @@ -36,7 +43,7 @@ const [activeTabs, setActiveTabs] = useState( agentTools: "contractTool", dataSources: "dataSource", verifications: "dataReputation", - }, + } ); useEffect(() => { @@ -74,14 +81,14 @@ const content = { setGlobalTagFilter: (value) => setGlobalTagFilter(value), }; return ( -
-

{group.title}

+
+ {group.title} -
+ ); }, dashboard: () => { @@ -114,7 +121,7 @@ const renderContent = () => { return content.subGroups( activeGroup, schema[activeGroup], - globalTagFilter, // forces re-render, gets passed through Storage + globalTagFilter // forces re-render, gets passed through Storage ); } }; @@ -163,12 +170,13 @@ const handleTagClick = (tag) => { }); setActiveGroup(category); }; + return (
+ {renderContent()}
diff --git a/nexus/components/src/AI/Overview.jsx b/nexus/components/src/AI/Overview.jsx index 1f626c9..dac04d0 100644 --- a/nexus/components/src/AI/Overview.jsx +++ b/nexus/components/src/AI/Overview.jsx @@ -1,5 +1,5 @@ const Wrapper = styled.div` - --section-gap: 20px; + --section-gap: 2rem; --text-hero: 500 56px/1 "FK Grotesk", "Mona Sans", sans-serif; gap: var(--section-gap); display: flex; @@ -13,12 +13,6 @@ const Text = styled.p` color: var(--${(p) => p.$color ?? "sand12"}); margin: 0; letter-spacing: ${(p) => p.$letterSpacing}; - - display: -webkit-box; - overflow: hidden; - -webkit-line-clamp: ${(p) => p.$overflowLines ?? "2"}; - -webkit-box-orient: vertical; - text-overflow: ellipsis; word-break: break-word; @media (max-width: 900px) { @@ -83,10 +77,6 @@ const Grid = styled.div` const Section = styled.div` position: relative; - - @media (max-width: 900px) { - padding: 0 14px; - } `; const Container = styled.div` @@ -161,7 +151,6 @@ const ButtonMenuWrapper = styled.button` const ButtonLinkWrapper = styled("Link")` all: unset; - display: flex; gap: ${(p) => p.$gap}; align-items: ${(p) => p.$alignItems}; @@ -317,7 +306,7 @@ query ListQuery($offset: Int, $limit: Int) { }; const queryName = "ListQuery"; const loadItemsQueryApi = VM.require( - "${REPL_ACCOUNT}/widget/Entities.QueryApi.Client", + "${REPL_ACCOUNT}/widget/Entities.QueryApi.Client" )?.loadItems; if (!loadItemsQueryApi) { return

Loading modules...

; @@ -436,7 +425,7 @@ const TrendingApp = ({ href, url, name, loading }) => ( ); return ( - +
- + -
+
- + Explore agents built by the NEAR community.} > - + {topRatingApps.map((app) => (