diff --git a/src/components/safe-apps/SafeAppList/index.tsx b/src/components/safe-apps/SafeAppList/index.tsx index 86d00ba73e..31b2777d9a 100644 --- a/src/components/safe-apps/SafeAppList/index.tsx +++ b/src/components/safe-apps/SafeAppList/index.tsx @@ -2,28 +2,28 @@ import { useCallback } from 'react' import type { SafeAppData } from '@safe-global/safe-gateway-typescript-sdk' import classnames from 'classnames' -import SafeAppsFilters from '@/components/safe-apps/SafeAppsFilters' import SafeAppCard, { GRID_VIEW_MODE } from '@/components/safe-apps/SafeAppCard' import type { SafeAppsViewMode } from '@/components/safe-apps/SafeAppCard' import AddCustomSafeAppCard from '@/components/safe-apps/AddCustomSafeAppCard' import SafeAppPreviewDrawer from '@/components/safe-apps/SafeAppPreviewDrawer' import SafeAppsListHeader from '@/components/safe-apps/SafeAppsListHeader' import SafeAppsZeroResultsPlaceholder from '@/components/safe-apps/SafeAppsZeroResultsPlaceholder' -import useSafeAppsFilters from '@/hooks/safe-apps/useSafeAppsFilters' import useSafeAppPreviewDrawer from '@/hooks/safe-apps/useSafeAppPreviewDrawer' import css from './styles.module.css' import { Skeleton } from '@mui/material' import useLocalStorage from '@/services/local-storage/useLocalStorage' import { useOpenedSafeApps } from '@/hooks/safe-apps/useOpenedSafeApps' +import { motion, AnimatePresence } from 'framer-motion' type SafeAppListProps = { safeAppsList: SafeAppData[] safeAppsListLoading?: boolean bookmarkedSafeAppsId?: Set onBookmarkSafeApp?: (safeAppId: number) => void - showFilters?: boolean addCustomApp?: (safeApp: SafeAppData) => void removeCustomApp?: (safeApp: SafeAppData) => void + title: string + query?: string } const VIEW_MODE_KEY = 'SafeApps_viewMode' @@ -33,18 +33,16 @@ const SafeAppList = ({ safeAppsListLoading, bookmarkedSafeAppsId, onBookmarkSafeApp, - showFilters, addCustomApp, removeCustomApp, + title, + query, }: SafeAppListProps) => { const [safeAppsViewMode = GRID_VIEW_MODE, setSafeAppsViewMode] = useLocalStorage(VIEW_MODE_KEY) const { isPreviewDrawerOpen, previewDrawerApp, openPreviewDrawer, closePreviewDrawer } = useSafeAppPreviewDrawer() const { openedSafeAppIds } = useOpenedSafeApps() - const { filteredApps, query, setQuery, setSelectedCategories, setOptimizedWithBatchFilter, selectedCategories } = - useSafeAppsFilters(safeAppsList) - - const showZeroResultsPlaceholder = query && filteredApps.length === 0 + const showZeroResultsPlaceholder = query && safeAppsList.length === 0 const handleSafeAppClick = useCallback( (safeApp: SafeAppData) => { @@ -59,20 +57,10 @@ const SafeAppList = ({ return ( <> - {/* Safe Apps Filters */} - {showFilters && ( - - )} - {/* Safe Apps List Header */} @@ -98,20 +86,28 @@ const SafeAppList = ({ ))} - {/* Flat list filtered by search query */} - {filteredApps.map((safeApp) => ( -
  • - -
  • - ))} + + {/* Flat list filtered by search query */} + {safeAppsList.map((safeApp) => ( + + + + ))} + {/* Zero results placeholder */} diff --git a/src/components/safe-apps/SafeAppList/styles.module.css b/src/components/safe-apps/SafeAppList/styles.module.css index c13941edc1..fe2c4e4fd1 100644 --- a/src/components/safe-apps/SafeAppList/styles.module.css +++ b/src/components/safe-apps/SafeAppList/styles.module.css @@ -2,7 +2,7 @@ display: grid; grid-gap: var(--space-3); list-style-type: none; - padding: 0; + padding: 0 0 var(--space-1); } .safeAppsGridViewContainer { diff --git a/src/components/safe-apps/SafeAppsListHeader/index.tsx b/src/components/safe-apps/SafeAppsListHeader/index.tsx index 9551628d7c..e567a71b6f 100644 --- a/src/components/safe-apps/SafeAppsListHeader/index.tsx +++ b/src/components/safe-apps/SafeAppsListHeader/index.tsx @@ -12,17 +12,18 @@ import css from './styles.module.css' import { SAFE_APPS_EVENTS, trackEvent } from '@/services/analytics' type SafeAppsListHeaderProps = { + title: string amount?: number safeAppsViewMode: SafeAppsViewMode setSafeAppsViewMode: (viewMode: SafeAppsViewMode) => void } -const SafeAppsListHeader = ({ amount, safeAppsViewMode, setSafeAppsViewMode }: SafeAppsListHeaderProps) => { +const SafeAppsListHeader = ({ title, amount, safeAppsViewMode, setSafeAppsViewMode }: SafeAppsListHeaderProps) => { return ( - + {/* Safe Apps count */} - - ALL ({amount || 0}) + + {title} ({amount || 0}) {/* switch Safe Apps view mode radio buttons */} diff --git a/src/components/sidebar/SidebarNavigation/config.tsx b/src/components/sidebar/SidebarNavigation/config.tsx index d3196aa5d6..9f8dbde18f 100644 --- a/src/components/sidebar/SidebarNavigation/config.tsx +++ b/src/components/sidebar/SidebarNavigation/config.tsx @@ -138,10 +138,6 @@ export const safeAppsNavItems = [ label: 'All apps', href: AppRoutes.apps.index, }, - { - label: 'Bookmarked apps', - href: AppRoutes.apps.bookmarked, - }, { label: 'My custom apps', href: AppRoutes.apps.custom, diff --git a/src/pages/apps/bookmarked.tsx b/src/pages/apps/bookmarked.tsx index 9b5b9def05..78cff66452 100644 --- a/src/pages/apps/bookmarked.tsx +++ b/src/pages/apps/bookmarked.tsx @@ -1,36 +1,21 @@ import type { NextPage } from 'next' import Head from 'next/head' - -import { useSafeApps } from '@/hooks/safe-apps/useSafeApps' -import SafeAppsHeader from '@/components/safe-apps/SafeAppsHeader' -import SafeAppList from '@/components/safe-apps/SafeAppList' -import SafeAppsSDKLink from '@/components/safe-apps/SafeAppsSDKLink' +import { useRouter } from 'next/router' +import { useEffect } from 'react' +import { AppRoutes } from '@/config/routes' const BookmarkedSafeApps: NextPage = () => { - const { - pinnedSafeApps: bookmarkedSafeApps, - pinnedSafeAppIds: bookmarkedSafeAppsId, - togglePin: onBookmarkSafeApp, - } = useSafeApps() - - return ( - <> - - {'Bookmarked Safe Apps'} - + const router = useRouter() - + // Redirect to /apps + useEffect(() => { + router.push({ pathname: AppRoutes.apps.index, query: { safe: router.query.safe } }) + }, [router]) - - -
    - -
    - + return ( + + {'Safe{Wallet} – Safe Apps'} + ) } diff --git a/src/pages/apps/custom.tsx b/src/pages/apps/custom.tsx index 56932a0511..b7690100d8 100644 --- a/src/pages/apps/custom.tsx +++ b/src/pages/apps/custom.tsx @@ -38,6 +38,7 @@ const CustomSafeApps: NextPage = () => {
    { const router = useRouter() + const { remoteSafeApps, remoteSafeAppsLoading, pinnedSafeApps, pinnedSafeAppIds, togglePin } = useSafeApps() + const { filteredApps, query, setQuery, setSelectedCategories, setOptimizedWithBatchFilter, selectedCategories } = + useSafeAppsFilters(remoteSafeApps) - const { - remoteSafeApps, - remoteSafeAppsLoading, - pinnedSafeAppIds: bookmarkedSafeAppsId, - togglePin: onBookmarkSafeApp, - } = useSafeApps() + const nonPinnedApps = useMemo( + () => remoteSafeApps.filter((app) => !pinnedSafeAppIds.has(app.id)), + [remoteSafeApps, pinnedSafeAppIds], + ) // Redirect to an individual safe app page if the appUrl is in the query params useEffect(() => { @@ -38,12 +41,33 @@ const SafeApps: NextPage = () => {
    - + + {/* Pinned apps */} + {!query && ( + + )} + + {/* All apps */} +