soapbox/app/soapbox/features/onboarding/steps/suggested-accounts-step.tsx

117 wiersze
3.7 KiB
TypeScript

import debounce from 'lodash/debounce';
import * as React from 'react';
import { FormattedMessage } from 'react-intl';
import { useDispatch } from 'react-redux';
import { fetchSuggestions } from 'soapbox/actions/suggestions';
import ScrollableList from 'soapbox/components/scrollable_list';
import { Button, Card, CardBody, Stack, Text } from 'soapbox/components/ui';
import AccountContainer from 'soapbox/containers/account_container';
import { useAppSelector } from 'soapbox/hooks';
const SuggestedAccountsStep = ({ onNext }: { onNext: () => void }) => {
const dispatch = useDispatch();
const suggestions = useAppSelector((state) => state.suggestions.items);
const hasMore = useAppSelector((state) => !!state.suggestions.next);
const isLoading = useAppSelector((state) => state.suggestions.isLoading);
const handleLoadMore = debounce(() => {
if (isLoading) {
return null;
}
return dispatch(fetchSuggestions());
}, 300);
React.useEffect(() => {
dispatch(fetchSuggestions({ limit: 20 }));
}, []);
const renderSuggestions = () => {
return (
<div className='sm:pt-4 sm:pb-10 flex flex-col'>
<ScrollableList
isLoading={isLoading}
scrollKey='suggestions'
onLoadMore={handleLoadMore}
hasMore={hasMore}
useWindowScroll={false}
style={{ height: 320 }}
>
{suggestions.map((suggestion) => (
<div key={suggestion.account} className='py-2'>
<AccountContainer
// @ts-ignore: TS thinks `id` is passed to <Account>, but it isn't
id={suggestion.account}
showProfileHoverCard={false}
withLinkToProfile={false}
/>
</div>
))}
</ScrollableList>
</div>
);
};
const renderEmpty = () => {
return (
<div className='bg-primary-50 dark:bg-slate-700 my-2 rounded-lg text-center p-8'>
<Text>
<FormattedMessage id='empty_column.follow_recommendations' defaultMessage='Looks like no suggestions could be generated for you. You can try using search to look for people you might know or explore trending hashtags.' />
</Text>
</div>
);
};
const renderBody = () => {
if (suggestions.isEmpty()) {
return renderEmpty();
} else {
return renderSuggestions();
}
};
return (
<Card variant='rounded' size='xl'>
<CardBody>
<div>
<div className='pb-4 sm:pb-10 mb-4 border-b border-gray-200 border-solid -mx-4 sm:-mx-10'>
<Stack space={2}>
<Text size='2xl' align='center' weight='bold'>
<FormattedMessage id='onboarding.suggestions.title' defaultMessage='Suggested accounts' />
</Text>
<Text theme='muted' align='center'>
<FormattedMessage id='onboarding.suggestions.subtitle' defaultMessage='Here are a few of the most popular accounts you might like.' />
</Text>
</Stack>
</div>
{renderBody()}
<div className='sm:w-2/3 md:w-1/2 mx-auto'>
<Stack>
<Stack justifyContent='center' space={2}>
<Button
block
theme='primary'
onClick={onNext}
>
<FormattedMessage id='onboarding.done' defaultMessage='Done' />
</Button>
<Button block theme='link' type='button' onClick={onNext}>
<FormattedMessage id='onboarding.skip' defaultMessage='Skip for now' />
</Button>
</Stack>
</Stack>
</div>
</div>
</CardBody>
</Card>
);
};
export default SuggestedAccountsStep;