import { h, Component } from 'preact'; import PropTypes from 'prop-types'; import he from 'he'; import { getContentOfToken } from '../utilities'; import { locale } from '../../utilities/locale'; import { Navigation } from './Navigation'; import { Spinner } from '@crayons/Spinner/Spinner'; function groupFollowsByType(array) { return array.reduce((returning, item) => { const type = item.type_identifier; returning[type] = (returning[type] || []).concat(item); return returning; }, {}); } function groupFollowIdsByType(array) { return array.reduce((returning, item) => { const type = item.type_identifier; returning[type] = (returning[type] || []).concat({ id: item.id }); return returning; }, {}); } export class FollowUsers extends Component { constructor(props) { super(props); this.handleClick = this.handleClick.bind(this); this.handleComplete = this.handleComplete.bind(this); this.state = { follows: [], selectedFollows: [], loading: true, }; } componentDidMount() { fetch('/onboarding/users_and_organizations', { headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, credentials: 'same-origin', }) .then((response) => response.json()) .then((data) => { this.setState({ selectedFollows: data, follows: data, loading: false, }); }); const csrfToken = getContentOfToken('csrf-token'); fetch('/onboarding', { method: 'PATCH', headers: { 'X-CSRF-Token': csrfToken, 'Content-Type': 'application/json', }, body: JSON.stringify({ user: { last_onboarding_page: 'v2: follow users page' }, }), credentials: 'same-origin', }); } handleComplete() { const csrfToken = getContentOfToken('csrf-token'); const { selectedFollows } = this.state; const { next } = this.props; const idsGroupedByType = groupFollowIdsByType(selectedFollows); fetch('/api/follows', { method: 'POST', headers: { 'X-CSRF-Token': csrfToken, 'Content-Type': 'application/json', }, body: JSON.stringify({ users: idsGroupedByType['user'], organizations: idsGroupedByType['organization'], }), credentials: 'same-origin', }); next(); } handleSelectAll() { const { selectedFollows, follows } = this.state; if (selectedFollows.length === follows.length) { this.setState({ selectedFollows: [], }); } else { this.setState({ selectedFollows: follows, }); } } handleClick(follow) { let { selectedFollows } = this.state; if (!selectedFollows.includes(follow)) { this.setState((prevState) => ({ selectedFollows: [...prevState.selectedFollows, follow], })); } else { selectedFollows = [...selectedFollows]; const indexToRemove = selectedFollows.indexOf(follow); selectedFollows.splice(indexToRemove, 1); this.setState({ selectedFollows, }); } } renderFollowCount() { const { follows, selectedFollows } = this.state; let followingStatus; if (selectedFollows.length === 0) { followingStatus = locale('core.not_following'); } else { const groups = groupFollowsByType(selectedFollows); let together = []; for (const type in groups) { const counted = locale(`core.counted_${type}`, { count: groups[type].length, }); together = together.concat(counted); } const anded_together = together.join(` ${locale('core.and')} `); if (selectedFollows.length === follows.length) { followingStatus = `${locale('core.following_everyone', { details: anded_together, })}`; } else { followingStatus = `${locale( 'core.you_are_following', )} ${anded_together}`; } } const klassName = selectedFollows.length > 0 ? 'fw-bold color-base-60 inline-block fs-base' : 'color-base-60 inline-block fs-base'; return
{followingStatus} -
; } renderFollowToggle() { const { follows, selectedFollows } = this.state; let followText = ''; if (selectedFollows.length !== follows.length) { if (follows.length === 1) { followText = `Select ${follows.length}`; } else { followText = `Select all ${follows.length}`; } } else { followText = 'Deselect all'; } return ( ); } render() { const { follows, selectedFollows, loading } = this.state; const { prev, slidesCount, currentSlideIndex } = this.props; const canSkip = selectedFollows.length === 0; return (