refactor: ui explore view responsivity (#236)
* refactor: clean up nfa search code and add base responsivity * refactor: clean up nfa list code * refactor: rename explore header fragment files * refactor: nfa list items sizing * feat: add vertical padding for page content * refactor: make navbar not break the layout
This commit is contained in:
parent
21b9660164
commit
0354877581
|
|
@ -6,7 +6,7 @@ import { AppPage, ToastProvider } from './components';
|
||||||
import {
|
import {
|
||||||
ComponentsTest,
|
ComponentsTest,
|
||||||
CreateAP,
|
CreateAP,
|
||||||
Explore,
|
ExploreView,
|
||||||
IndexedNFAView,
|
IndexedNFAView,
|
||||||
Mint,
|
Mint,
|
||||||
} from './views';
|
} from './views';
|
||||||
|
|
@ -19,7 +19,7 @@ export const App: React.FC = () => {
|
||||||
<ToastProvider />
|
<ToastProvider />
|
||||||
<AppPage>
|
<AppPage>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/" element={<Explore />} />
|
<Route path="/" element={<ExploreView />} />
|
||||||
<Route path="/mint" element={<Mint />} />
|
<Route path="/mint" element={<Mint />} />
|
||||||
<Route path="/create-ap/:id" element={<CreateAP />} />
|
<Route path="/create-ap/:id" element={<CreateAP />} />
|
||||||
<Route path="/nfa/:id" element={<IndexedNFAView />} />
|
<Route path="/nfa/:id" element={<IndexedNFAView />} />
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ export abstract class NavBarStyles {
|
||||||
backgroundColor: '$black',
|
backgroundColor: '$black',
|
||||||
zIndex: '$sticky',
|
zIndex: '$sticky',
|
||||||
height: '$22',
|
height: '$22',
|
||||||
|
overflow: 'hidden', // TODO: this must be worked on for responsive layout
|
||||||
});
|
});
|
||||||
|
|
||||||
static readonly Content = styled('div', {
|
static readonly Content = styled('div', {
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,8 @@ export abstract class PageStyles {
|
||||||
public static readonly Content = styled('div', {
|
public static readonly Content = styled('div', {
|
||||||
width: '100%',
|
width: '100%',
|
||||||
minHeight: '85vh',
|
minHeight: '85vh',
|
||||||
maxWidth: '$7xl',
|
maxWidth: '$6xl',
|
||||||
|
padding: '0 $6',
|
||||||
margin: '0 auto',
|
margin: '0 auto',
|
||||||
display: 'grid',
|
display: 'grid',
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ export const NFACardStyles = {
|
||||||
Container: styled(Link, {
|
Container: styled(Link, {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
width: '14.6875rem',
|
minWidth: '12.5rem',
|
||||||
padding: 0,
|
padding: 0,
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
|
|
@ -60,6 +60,11 @@ export const NFACardStyles = {
|
||||||
fontSize: '$xl',
|
fontSize: '$xl',
|
||||||
fontWeight: '$medium',
|
fontWeight: '$medium',
|
||||||
lineHeight: 1.4,
|
lineHeight: 1.4,
|
||||||
|
|
||||||
|
maxWidth: 'auto',
|
||||||
|
overflow: 'hidden',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
}),
|
}),
|
||||||
Content: styled('span', {
|
Content: styled('span', {
|
||||||
all: 'unset',
|
all: 'unset',
|
||||||
|
|
@ -79,7 +84,7 @@ export const NFACardStyles = {
|
||||||
Skeleton: {
|
Skeleton: {
|
||||||
Preview: styled(Skeleton, {
|
Preview: styled(Skeleton, {
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: 'calc(14.6875rem - 2px)',
|
aspectRatio: 1,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
Title: styled(Skeleton, {
|
Title: styled(Skeleton, {
|
||||||
|
|
|
||||||
|
|
@ -60,8 +60,7 @@ export const NFACard: React.FC<NFACardProps> = forwardStyledRef<
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* TODO: treat names bigger than space in layout when designs are done */}
|
<S.Title title={data.name}>{data.name}</S.Title>
|
||||||
<S.Title>{data.name}</S.Title>
|
|
||||||
{/* TODO: set correct value when it gets available on contract side */}
|
{/* TODO: set correct value when it gets available on contract side */}
|
||||||
<Badge verified={Math.random() > 0.5} />
|
<Badge verified={Math.random() > 0.5} />
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { Button } from '@/components';
|
||||||
|
|
||||||
import { ExploreHeaderStyles as S } from './explore-header.styles';
|
import { ExploreHeaderStyles as S } from './explore-header.styles';
|
||||||
|
|
||||||
export const ExploreHeader: React.FC = () => (
|
export const ExploreHeaderFragment: React.FC = () => (
|
||||||
<S.Container>
|
<S.Container>
|
||||||
<S.Text>
|
<S.Text>
|
||||||
<S.GrayText>
|
<S.GrayText>
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './explore-header.fragment';
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
import { Flex } from '@/components';
|
|
||||||
|
|
||||||
import { Explore } from '../explore.context';
|
|
||||||
import { NFAListFragment } from './nfa-list';
|
|
||||||
import { NFASearchFragment } from './nfa-search';
|
|
||||||
|
|
||||||
export const ExploreListContainer: React.FC = () => {
|
|
||||||
return (
|
|
||||||
<Flex css={{ flexDirection: 'column' }}>
|
|
||||||
<Explore.Provider>
|
|
||||||
<NFASearchFragment />
|
|
||||||
<NFAListFragment />
|
|
||||||
</Explore.Provider>
|
|
||||||
</Flex>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
import { Explore } from '../explore.context';
|
||||||
|
import { NFAListFragment } from './nfa-list.fragment';
|
||||||
|
import { NFASearchFragment } from './nfa-search.fragment';
|
||||||
|
|
||||||
|
export const ExploreListFragment: React.FC = () => {
|
||||||
|
return (
|
||||||
|
<Explore.Provider>
|
||||||
|
<NFASearchFragment />
|
||||||
|
<NFAListFragment />
|
||||||
|
</Explore.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -1 +1 @@
|
||||||
export * from './explore-list-container';
|
export * from './explore-list.fragment';
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
import { useQuery } from '@apollo/client';
|
import { useQuery } from '@apollo/client';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
import { Flex, NFACard, NFACardSkeleton } from '@/components';
|
import { NFACard, NFACardSkeleton } from '@/components';
|
||||||
import { lastNFAsPaginatedDocument } from '@/graphclient';
|
import { lastNFAsPaginatedDocument } from '@/graphclient';
|
||||||
import { useWindowScrollEnd } from '@/hooks';
|
import { useWindowScrollEnd } from '@/hooks';
|
||||||
|
|
||||||
import { Explore } from '../../explore.context';
|
import { Explore } from '../explore.context';
|
||||||
|
import { NFAListFragmentStyles as S } from './nfa-list.styles';
|
||||||
|
|
||||||
const pageSize = 10; //Set this size to test pagination
|
const pageSize = 10; //Set this size to test pagination
|
||||||
|
|
||||||
|
|
@ -15,6 +16,8 @@ const LoadingSkeletons: React.FC = () => (
|
||||||
<NFACardSkeleton />
|
<NFACardSkeleton />
|
||||||
<NFACardSkeleton />
|
<NFACardSkeleton />
|
||||||
<NFACardSkeleton />
|
<NFACardSkeleton />
|
||||||
|
<NFACardSkeleton />
|
||||||
|
<NFACardSkeleton />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -61,29 +64,16 @@ export const NFAListFragment: React.FC = () => {
|
||||||
if (queryError) return <div>Error</div>; //TODO handle error
|
if (queryError) return <div>Error</div>; //TODO handle error
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex
|
<S.Container>
|
||||||
css={{
|
{tokens.map((token) => (
|
||||||
flexDirection: 'column',
|
<NFACard data={token} key={token.id} />
|
||||||
gap: '$2',
|
))}
|
||||||
my: '$6',
|
|
||||||
minHeight: '50vh',
|
{isLoading && <LoadingSkeletons />}
|
||||||
marginBottom: '30vh', // TODO: remove this if we add page footer
|
|
||||||
}}
|
{!isLoading && tokens.length === 0 && (
|
||||||
>
|
<S.EmptyMessage>Nothing found.</S.EmptyMessage>
|
||||||
<Flex css={{ gap: '$6', flexWrap: 'wrap' }}>
|
)}
|
||||||
{tokens.map((token) => (
|
</S.Container>
|
||||||
<NFACard data={token} key={token.id} />
|
|
||||||
))}
|
|
||||||
{isLoading && <LoadingSkeletons />}
|
|
||||||
{!isLoading && tokens.length === 0 && (
|
|
||||||
// TODO: update this after designs are done
|
|
||||||
<div
|
|
||||||
className={`relative cursor-default select-none pt-2 px-3.5 pb-4 text-slate11 text-center`}
|
|
||||||
>
|
|
||||||
Nothing found.
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { styled } from '@/theme';
|
||||||
|
|
||||||
|
export const NFAListFragmentStyles = {
|
||||||
|
Container: styled('div', {
|
||||||
|
display: 'grid',
|
||||||
|
gridTemplateColumns: 'repeat(auto-fill, minmax(12.5rem, 1fr))',
|
||||||
|
alignItems: 'flex-start',
|
||||||
|
flexWrap: 'wrap',
|
||||||
|
gap: '$6',
|
||||||
|
my: '$6',
|
||||||
|
minHeight: '50vh',
|
||||||
|
marginBottom: '30vh', // TODO: remove this if we add page footer
|
||||||
|
|
||||||
|
'@media (min-width: 1080px)': {
|
||||||
|
gridTemplateColumns: 'repeat(auto-fill, minmax(15rem, 1fr))',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
EmptyMessage: styled('span', {
|
||||||
|
padding: '$2 $3 $4 $3',
|
||||||
|
textAlign: 'center',
|
||||||
|
color: '$slate11',
|
||||||
|
width: '100%',
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
export * from './nfa-list';
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
|
||||||
import { Dropdown, DropdownItem, Flex, Input } from '@/components';
|
import { Dropdown, DropdownItem, Input } from '@/components';
|
||||||
import { useDebounce } from '@/hooks';
|
import { useDebounce } from '@/hooks';
|
||||||
|
|
||||||
import { Explore } from '../explore.context';
|
import { Explore } from '../explore.context';
|
||||||
import { ResultsContainer, ResultsNumber, ResultsText } from './results.styles';
|
import { NFASearchFragmentStyles as S } from './nfa-search.styles';
|
||||||
|
|
||||||
const orderResults: DropdownItem[] = [
|
const orderResults: DropdownItem[] = [
|
||||||
{ value: 'newest', label: 'Newest' },
|
{ value: 'newest', label: 'Newest' },
|
||||||
|
|
@ -62,17 +62,18 @@ export const NFASearchFragment: React.FC = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex css={{ justifyContent: 'space-between' }}>
|
<S.Container>
|
||||||
<ResultsContainer>
|
<S.Data.Wrapper>
|
||||||
<ResultsText>All NFAs </ResultsText>
|
<S.Data.Text>All NFAs </S.Data.Text>
|
||||||
<ResultsNumber>(3,271)</ResultsNumber>
|
<S.Data.Number>(3,271)</S.Data.Number>
|
||||||
</ResultsContainer>
|
</S.Data.Wrapper>
|
||||||
<Flex css={{ gap: '$3' }}>
|
|
||||||
|
<S.Input.Wrapper>
|
||||||
<Input
|
<Input
|
||||||
placeholder="Search"
|
placeholder="Search"
|
||||||
leftIcon="search"
|
leftIcon="search"
|
||||||
css={{ width: '23rem' }}
|
|
||||||
onChange={handleSearchChange}
|
onChange={handleSearchChange}
|
||||||
|
wrapperClassName="flex-1"
|
||||||
/>
|
/>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
items={orderResults}
|
items={orderResults}
|
||||||
|
|
@ -82,7 +83,7 @@ export const NFASearchFragment: React.FC = () => {
|
||||||
textColor="slate11"
|
textColor="slate11"
|
||||||
optionsWidth="40"
|
optionsWidth="40"
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</S.Input.Wrapper>
|
||||||
</Flex>
|
</S.Container>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
import { Flex } from '@/components';
|
||||||
|
import { styled } from '@/theme';
|
||||||
|
|
||||||
|
export const NFASearchFragmentStyles = {
|
||||||
|
Container: styled(Flex, {
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
flexWrap: 'wrap',
|
||||||
|
gap: '$3',
|
||||||
|
}),
|
||||||
|
|
||||||
|
Data: {
|
||||||
|
Wrapper: styled('div', {
|
||||||
|
fontSize: '$xl',
|
||||||
|
fontWeight: '$bold',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
}),
|
||||||
|
|
||||||
|
Text: styled('span', {
|
||||||
|
color: '$slate12',
|
||||||
|
}),
|
||||||
|
|
||||||
|
Number: styled('span', {
|
||||||
|
color: '$slate11',
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
|
||||||
|
Input: {
|
||||||
|
Wrapper: styled(Flex, {
|
||||||
|
gap: '$3',
|
||||||
|
width: '100%',
|
||||||
|
maxWidth: '30rem',
|
||||||
|
justifySelf: 'center',
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
import { styled } from '@/theme';
|
|
||||||
|
|
||||||
export const ResultsContainer = styled('div', {
|
|
||||||
fontSize: '$xl',
|
|
||||||
fontWeight: '$bold',
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
});
|
|
||||||
|
|
||||||
export const ResultsText = styled('span', {
|
|
||||||
color: '$slate12',
|
|
||||||
});
|
|
||||||
|
|
||||||
export const ResultsNumber = styled('span', {
|
|
||||||
color: '$slate11',
|
|
||||||
});
|
|
||||||
|
|
@ -4,7 +4,5 @@ import { styled } from '@/theme';
|
||||||
export abstract class Explore {
|
export abstract class Explore {
|
||||||
static readonly Container = styled(Flex, {
|
static readonly Container = styled(Flex, {
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
width: '63.4rem', //TODO replace for max-width
|
|
||||||
margin: '0 auto',
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
import { Explore as ES } from './explore.styles';
|
import { Explore as ES } from './explore.styles';
|
||||||
import { ExploreHeader } from './explore-header';
|
import { ExploreHeaderFragment } from './explore-header';
|
||||||
import { ExploreListContainer } from './explore-list';
|
import { ExploreListFragment } from './explore-list';
|
||||||
|
|
||||||
export const Explore: React.FC = () => {
|
export const ExploreView: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
<ES.Container>
|
<ES.Container>
|
||||||
<ExploreHeader />
|
<ExploreHeaderFragment />
|
||||||
<ExploreListContainer />
|
<ExploreListFragment />
|
||||||
</ES.Container>
|
</ES.Container>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue