From 21647a56e49c5b733af845dfc40e15f2e413c0e5 Mon Sep 17 00:00:00 2001 From: "heykd.eth" <65736142+thekidnamedkd@users.noreply.github.com> Date: Fri, 25 Oct 2024 08:54:17 -0700 Subject: [PATCH 1/3] feat(APP-3649): Add JSON with test data for 'Featured' tab (#1408) --- src/assets/data/featured-daos.json | 48 ++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/assets/data/featured-daos.json diff --git a/src/assets/data/featured-daos.json b/src/assets/data/featured-daos.json new file mode 100644 index 000000000..aa4e03184 --- /dev/null +++ b/src/assets/data/featured-daos.json @@ -0,0 +1,48 @@ +[ + { + "name": "JankCryptoPioneers", + "description": "A DAO dedicated to pioneering blockchain innovations and fostering decentralized technologies.", + "logo": "https://example.com/avatars/cryptopioneers.png", + "network": "ethereum", + "daoAddress": "0x1234567890abcdef1234567890abcdef12345678", + "overrideUrl": "https://cryptopioneers.io/custom-link" + }, + { + "name": "DeFiMasters", + "description": "Mastering decentralized finance through community-driven projects and initiatives.", + "logo": "https://example.com/avatars/defimasters.png", + "network": "polygon", + "daoAddress": "0xabcdef1234567890abcdef1234567890abcdef12" + }, + { + "name": "NFTCollectors", + "description": "A vibrant community of NFT enthusiasts focused on collecting and promoting unique digital assets.", + "logo": "https://example.com/avatars/nftcollectors.png", + "network": "polygon", + "daoAddress": "0x7890abcdef1234567890abcdef1234567890abcd", + "overrideUrl": "https://nftcollectors.io" + }, + { + "name": "GreenChain", + "description": "Promoting sustainable blockchain solutions and eco-friendly crypto practices.", + "logo": "https://example.com/avatars/greenchain.png", + "network": "sepolia", + "daoAddress": "0x4567890abcdef1234567890abcdef1234567890ef" + }, + { + "name": "MetaBuilders", + "description": "Building the future of the metaverse through collaborative projects and virtual initiatives.", + "logo": "https://example.com/avatars/metabuilders.png", + "network": "arbitrum", + "daoAddress": "0xabcdef7890abcdef1234567890abcdef12345678", + "overrideUrl": "https://metabuilders.io/projects" + }, + { + "name": "FreakyDeakyDAO", + "description": "Here to be freaky and deaky, this DAO is all about pushing the boundaries of decentralized creativity.", + "logo": "https://example.com/avatars/freakydeakydao.png", + "network": "arbitrum", + "daoAddress": "0x1234567890abcdef1234567890abcdef12345678", + "overrideUrl": "https://freakydeakydao.io" + } +] From 79aa203ae8627fa9416c08eaa6f9fd8f1f8115ac Mon Sep 17 00:00:00 2001 From: "heykd.eth" <65736142+thekidnamedkd@users.noreply.github.com> Date: Tue, 29 Oct 2024 07:00:46 -0700 Subject: [PATCH 2/3] feat(APP-3649): Implement "Featured" tab on Explorer page (#1407) --- src/assets/locales/en/common.json | 7 +- src/components/daoCard/index.tsx | 36 ++- src/containers/daoExplorer/daoExplorer.tsx | 307 +++++++++++++-------- src/containers/daoFilterModal/data.ts | 10 +- src/containers/daoFilterModal/index.tsx | 47 +--- src/hooks/useFeaturedDaos.ts | 20 ++ src/pages/explore.tsx | 1 - 7 files changed, 239 insertions(+), 189 deletions(-) create mode 100644 src/hooks/useFeaturedDaos.ts diff --git a/src/assets/locales/en/common.json b/src/assets/locales/en/common.json index bbead2169..2c599e538 100644 --- a/src/assets/locales/en/common.json +++ b/src/assets/locales/en/common.json @@ -1018,9 +1018,7 @@ "myDaos": "My DAOs", "popular": "Popular", "newest": "Newest", - "walletBased": "Wallet-based", - "showMore": "Show more", - "tokenBased": "Token-based" + "showMore": "Show more" }, "activeProposals": "Active proposals", "showMore": "Show more", @@ -1039,7 +1037,8 @@ "linkURL": "https://aragon.org/education-portal" }, "toggleFilter": { - "Favourites": "Following", + "favourites": "Following", + "featuredDAOs": "Featured", "allDAOs": "All DAOs ", "member": "Member" }, diff --git a/src/components/daoCard/index.tsx b/src/components/daoCard/index.tsx index 0d63afada..56dc89b24 100644 --- a/src/components/daoCard/index.tsx +++ b/src/components/daoCard/index.tsx @@ -1,7 +1,6 @@ import {AvatarDao} from '@aragon/ods-old'; -import {Icon, IconType} from '@aragon/ods'; +import {AvatarIcon, Icon, IconType} from '@aragon/ods'; import React from 'react'; -import {useTranslation} from 'react-i18next'; import styled from 'styled-components'; import useScreen from 'hooks/useScreen'; import {generatePath, useHref} from 'react-router-dom'; @@ -11,15 +10,18 @@ import {toDisplayEns} from 'utils/library'; import {Dashboard} from 'utils/paths'; import {IDao} from 'services/aragon-backend/domain/dao'; +interface IDaoWithOverride extends IDao { + overrideUrl?: string; +} + export interface IDaoCardProps { - dao: IDao; + dao: IDaoWithOverride; } export const DaoCard = (props: IDaoCardProps) => { const {dao} = props; - const {name, daoAddress, logo, ens, description, network, pluginName} = dao; + const {name, daoAddress, logo, ens, description, network, overrideUrl} = dao; - const {t} = useTranslation(); const {isDesktop} = useScreen(); const {avatar} = useResolveDaoAvatar(logo); @@ -29,23 +31,18 @@ export const DaoCard = (props: IDaoCardProps) => { }); const daoUrl = useHref(daoPage); - // TODO: This should be changed for new plugin types - const daoType = - pluginName === 'token-voting.plugin.dao.eth' || - pluginName === 'token-voting-repo' - ? t('explore.explorer.tokenBased') - : t('explore.explorer.walletBased'); + const resolvedDaoUrl = overrideUrl ?? daoUrl; return ( - +
{name} -

- {toDisplayEns(ens)} -

{description} @@ -58,10 +55,9 @@ export const DaoCard = (props: IDaoCardProps) => { /> {CHAIN_METADATA[network].name} - - - {daoType} - + {overrideUrl != null && ( + + )}
); @@ -109,7 +105,7 @@ const Description = styled.p.attrs({ `; const DaoMetadataWrapper = styled.div.attrs({ - className: 'flex flex-row space-x-6', + className: 'flex flex-row justify-between items-center', })``; const IconLabel = styled.p.attrs({ className: 'text-neutral-600 ft-text-sm', diff --git a/src/containers/daoExplorer/daoExplorer.tsx b/src/containers/daoExplorer/daoExplorer.tsx index c345633f4..b956e4216 100644 --- a/src/containers/daoExplorer/daoExplorer.tsx +++ b/src/containers/daoExplorer/daoExplorer.tsx @@ -23,6 +23,8 @@ import { quickFilters, } from '../daoFilterModal/data'; import {Toggle, ToggleGroup} from '@aragon/ods'; +import {useFeaturedDaos} from 'hooks/useFeaturedDaos'; +import classNames from 'classnames'; const followedDaoToDao = (dao: NavigationDao): IDao => ({ creatorAddress: '' as Address, @@ -38,7 +40,7 @@ const followedDaoToDao = (dao: NavigationDao): IDao => ({ export const DaoExplorer = () => { const {t} = useTranslation(); - const {isConnected, address} = useWallet(); + const {isConnected, address, methods} = useWallet(); const [showAdvancedFilters, setShowAdvancedFilters] = useState(false); const [activeDropdown, setActiveDropdown] = useState(false); @@ -78,8 +80,6 @@ export const DaoExplorer = () => { if (!filters) return ''; - if (filters.quickFilter !== DEFAULT_FILTERS.quickFilter) count++; - // plugin Name filter if (filters.pluginNames?.length !== 0) count++; @@ -103,6 +103,9 @@ export const DaoExplorer = () => { const {isLoading, hasNextPage, isFetchingNextPage, fetchNextPage} = useFollowList ? followedDaosResult : newDaosResult; + const {data: featuredDaoList, isLoading: isLoadingFeaturedDaos} = + useFeaturedDaos(); + const totalDaos = useFollowList ? followedDaosResult.data?.pages[0].total ?? 0 : newDaosResult.data?.pages[0].total ?? 0; @@ -128,10 +131,47 @@ export const DaoExplorer = () => { const noDaosFound = isLoading === false && totalDaos === 0; + const noFeaturedDaosFound = + isLoadingFeaturedDaos === false && + featuredDaoList == null && + filters.quickFilter === 'featuredDaos'; + const handleClearFilters = () => { dispatch({type: FilterActionTypes.RESET, payload: DEFAULT_FILTERS}); }; + const handleWalletButtonClick = () => { + if (isConnected) { + return; + } + + methods.selectWallet().catch((err: Error) => { + console.error(err); + }); + }; + + const showSortFilter = filters.quickFilter !== 'featuredDaos' && isConnected; + + const filterGroupClassName = classNames('flex justify-between w-full', { + 'flex flex-col items-center gap-y-3 md:flex-row md:justify-between': + isConnected, + }); + + const toggleGroupClassName = classNames('flex flex-row w-full', { + 'grid w-full grid-cols-2 gap-1 text-center md:flex md:w-fit md:flex-row': + isConnected, + }); + + const toggleClassName = classNames({ + 'flex w-full justify-center md:w-fit': isConnected, + }); + + const buttonGroupContainerClassName = classNames('shrink-0', { + 'flex w-full md:w-fit justify-end': filters.quickFilter === 'featuredDaos', + 'flex gap-x-3 w-full md:w-fit justify-between': + isConnected && filters.quickFilter !== 'featuredDaos', + }); + /************************************************* * Render * *************************************************/ @@ -139,101 +179,118 @@ export const DaoExplorer = () => { {t('explore.explorer.title')} - +
- {quickFilters.map(f => { - return ( + {quickFilters + .filter(f => { + if ( + !isConnected && + (f.value === 'memberOf' || f.value === 'following') + ) { + return false; + } + return true; + }) + .map(f => ( - ); - })} + ))} - +
+ {showSortFilter && ( +
+ + {filters.quickFilter !== 'following' && ( + { + setActiveDropdown(e); + }} + customTrigger={ +
+ )} - {filters.quickFilter !== 'following' && ( - { - setActiveDropdown(e); - }} - customTrigger={ -
+
+ {noDaosFound || noFeaturedDaosFound ? ( { /> ) : ( - {filteredDaoList?.map( - (dao: IDao, index: React.Key | null | undefined) => ( - - ) + {filters.quickFilter === 'featuredDaos' ? ( + <> + {featuredDaoList?.map( + (dao: IDao, index: React.Key | null | undefined) => ( + + ) + )} + {isLoadingFeaturedDaos && ( + + )} + + ) : ( + <> + {filteredDaoList?.map( + (dao: IDao, index: React.Key | null | undefined) => ( + + ) + )} + {isLoading && } + )} - {isLoading && } )}
- {totalDaos != null && totalDaos > 0 && totalDaosShown > 0 && ( -
- {hasNextPage && ( - - )} - - {t('explore.pagination.label.amountOf DAOs', { - amount: totalDaosShown, - total: totalDaos, - })} - -
- )} + {totalDaos != null && + totalDaos > 0 && + totalDaosShown > 0 && + filters.quickFilter !== 'featuredDaos' && ( +
+ {hasNextPage && ( + + )} + + {t('explore.pagination.label.amountOf DAOs', { + amount: totalDaosShown, + total: totalDaos, + })} + +
+ )} = ({onClose}) => { iconLeft={IconType.CLOSE} variant="tertiary" size="sm" - responsiveSize={{lg: 'lg'}} + responsiveSize={{lg: 'md'}} onClick={onClose} /> @@ -92,11 +87,10 @@ const Header: React.FC = ({onClose}) => { type ContentProps = Pick; const ModalContent: React.FC = ({ - filters: {networks, quickFilter, pluginNames, showTestnets}, + filters: {networks, pluginNames, showTestnets}, onFilterChange, }) => { const {t} = useTranslation(); - const {isConnected} = useWallet(); const testnetsFilters = networkFilters.flatMap(f => f.testnet ? f.value : [] @@ -109,14 +103,6 @@ const ModalContent: React.FC = ({ /************************************************* * Callbacks and Handlers * *************************************************/ - const toggleQuickFilters = (value?: string | string[]) => { - if (value && !Array.isArray(value)) { - onFilterChange({ - type: FilterActionTypes.SET_QUICK_FILTER, - payload: value as QuickFilterValue, - }); - } - }; const toggleNetworks = (value?: string[]) => { onFilterChange({ @@ -152,29 +138,6 @@ const ModalContent: React.FC = ({ *************************************************/ return (
- {/* Quick Filters */} - - - {quickFilters.map(f => { - return ( - - ); - })} - - - {/* Blockchain Filters */} diff --git a/src/hooks/useFeaturedDaos.ts b/src/hooks/useFeaturedDaos.ts new file mode 100644 index 000000000..51f0d6cc9 --- /dev/null +++ b/src/hooks/useFeaturedDaos.ts @@ -0,0 +1,20 @@ +import {useQuery} from '@tanstack/react-query'; +import {IDao} from 'services/aragon-backend/domain/dao'; + +const FEATURED_DAOS_URL = + 'https://raw.githubusercontent.com/aragon/app/refs/heads/develop/src/assets/data/featured-daos.json'; + +const fetchFeaturedDaos = async (): Promise => { + const response = await fetch(FEATURED_DAOS_URL); + + if (!response.ok) { + throw new Error('Failed to fetch featured DAOs'); + } + + const data: IDao[] = await response.json(); + return data; +}; + +export const useFeaturedDaos = () => { + return useQuery({queryKey: ['featuredDaos'], queryFn: fetchFeaturedDaos}); +}; diff --git a/src/pages/explore.tsx b/src/pages/explore.tsx index 9cc139103..823cc37d6 100644 --- a/src/pages/explore.tsx +++ b/src/pages/explore.tsx @@ -1,7 +1,6 @@ import React, {useEffect} from 'react'; import 'react-responsive-carousel/lib/styles/carousel.min.css'; import styled from 'styled-components'; - import {GridLayout} from 'components/layout'; import Carousel from 'containers/carousel'; import {DaoExplorer} from 'containers/daoExplorer'; From 38c55664d9c6517bb569b9017397487fd235d477 Mon Sep 17 00:00:00 2001 From: "heykd.eth" <65736142+thekidnamedkd@users.noreply.github.com> Date: Tue, 29 Oct 2024 07:14:04 -0700 Subject: [PATCH 3/3] feat(APP-3648): Update hero section and layout of Explore page (#1409) --- index.html | 4 ++ src/assets/images/blueprintTexture.svg | 1 + src/assets/locales/en/common.json | 24 ++++--- src/components/ctaCard/data.ts | 7 +- src/components/ctaCard/index.tsx | 22 +++---- src/components/daoCard/index.tsx | 2 +- src/containers/carousel/index.tsx | 1 - src/containers/daoExplorer/daoExplorer.tsx | 6 +- src/containers/daoOverview/index.tsx | 1 - src/containers/explorerCta/index.tsx | 75 ++++++++++++++++++++++ src/containers/hero/index.tsx | 58 ++++------------- src/containers/navbar/exploreNav.tsx | 46 +++++++++---- src/pages/explore.tsx | 7 +- src/utils/paths.ts | 2 +- 14 files changed, 160 insertions(+), 96 deletions(-) create mode 100644 src/assets/images/blueprintTexture.svg create mode 100644 src/containers/explorerCta/index.tsx diff --git a/index.html b/index.html index 619e09137..0a8cef947 100644 --- a/index.html +++ b/index.html @@ -27,6 +27,10 @@ + \ No newline at end of file diff --git a/src/assets/locales/en/common.json b/src/assets/locales/en/common.json index 2c599e538..bfbae35d0 100644 --- a/src/assets/locales/en/common.json +++ b/src/assets/locales/en/common.json @@ -32,7 +32,7 @@ "subtitle": "Go back to explorer page" }, "navButtons": { - "connectWallet": "Connect wallet", + "connectWallet": "Connect", "giveFeedback": "Give feedback" }, "labels": { @@ -1010,8 +1010,8 @@ }, "explore": { "hero": { - "title": "Explore the DAO World", - "subtitle1": "Build your DAO, explore communities, and find inspiration for your project all in one place." + "title": "Governed on Aragon", + "subtitle1": "Explore the organizations using our modular governance stack to secure their onchain governance." }, "explorer": { "title": "Explore DAOs", @@ -1036,6 +1036,10 @@ "linkLabel": "Learn about DAOs", "linkURL": "https://aragon.org/education-portal" }, + "build": { + "linkLabel": "Build faster", + "linkURL": "https://docs.aragon.org" + }, "toggleFilter": { "favourites": "Following", "featuredDAOs": "Featured", @@ -1127,19 +1131,19 @@ }, "cta": { "create": { - "title": "Create your DAO", - "description": "Mint tokens, set governance parameters, and deploy your DAO on-chain in minutes with our no-code setup process.", + "title": "Create", + "description": "Easily deploy a new DAO on Aragon OSx in minutes with our simple, no-code deployment wizard.", "actionLabel": "Create a DAO" }, "learn": { - "title": "Learn about DAOs", - "description": "Find inspiration and learn about DAOs in our education portal designed for builders at every stage of the journey.", + "title": "Learn", + "description": "Master onchain governance with our Resource Library's case studies, guides, and expert insights into Aragon OSx.", "actionLabel": "Learn about DAOs" }, "build": { - "title": "Build faster", - "description": "Use our governance plugins to build a DAO, dApp, or anything you can imagine on the Aragon OSx protocol.", - "actionLabel": "Coming soon" + "title": "Build", + "description": "Take the DIY approach: build Aragon OSx plugins or your own application using our Governance UI Kit and App Template.", + "actionLabel": "Build a custom DAO" }, "404": { "titleLine1": "Oh no,", diff --git a/src/components/ctaCard/data.ts b/src/components/ctaCard/data.ts index 4596c829e..83b2bd791 100644 --- a/src/components/ctaCard/data.ts +++ b/src/components/ctaCard/data.ts @@ -14,6 +14,7 @@ const CTACards = [ imgSrc: createDaoImg, subtitle: i18n.t('cta.create.description'), title: i18n.t('cta.create.title'), + isPrimary: true, }, { actionAvailable: true, @@ -22,14 +23,16 @@ const CTACards = [ imgSrc: learnImg, subtitle: i18n.t('cta.learn.description'), title: i18n.t('cta.learn.title'), + isPrimary: false, }, { - actionAvailable: false, + actionAvailable: true, actionLabel: i18n.t('cta.build.actionLabel'), - path: '', + path: i18n.t('explore.build.linkURL'), imgSrc: buildFaster, subtitle: i18n.t('cta.build.description'), title: i18n.t('cta.build.title'), + isPrimary: false, }, ]; diff --git a/src/components/ctaCard/index.tsx b/src/components/ctaCard/index.tsx index 0724c4899..ba7559ffa 100644 --- a/src/components/ctaCard/index.tsx +++ b/src/components/ctaCard/index.tsx @@ -13,6 +13,7 @@ type Props = { onClick: (path: string) => void; subtitle: string; title: string; + isPrimary: boolean; }; const CTACard: React.FC = props => { @@ -27,10 +28,11 @@ const CTACard: React.FC = props => { ) : (