hellowin/kanca

View on GitHub
src/domain/metric/component/TopUserActivity.js

Summary

Maintainability
F
5 days
Test Coverage
// @flow
import React from 'react';
import Card from 'infra/component/Card';
import { timeRangeToString } from 'infra/service/util';
import type { TimeRangeMetric } from '../service/timeRangeMetric';
import uuid from 'uuid';

type UserTop = {
  name: string,
  picture: string,
  url?: string,
  total: number,
  percent: number,
}

export const TopUserActivityTypes = {
  SCORE: 'SCORE',
  POSTS: 'POSTS',
  COMMENTS: 'COMMENTS',
  POSTS_SHARES: 'POSTS_SHARES',
  POSTS_LIKES: 'POSTS_LIKES',
};

export type TopUserActivityType = $Keys<typeof TopUserActivityTypes>

const getUsers = (metric: TimeRangeMetric, type: TopUserActivityType): UserTop[] => {
  switch (type) {
    case TopUserActivityTypes.SCORE:
      return metric.usersMetric.userMetrics.sort((a, b) => b.getScore() - a.getScore()).slice(0, 10)
        .map(user => ({ ...user, total: user.getScore(), percent: +((user.getScore()/metric.usersMetric.userMetrics.map(usr => usr.getScore()).reduce((pre, cur) => pre + cur, 0))*100).toFixed(2) }));
    case TopUserActivityTypes.POSTS:
      return metric.usersMetric.sortByPostsCount().slice(0, 10)
        .map(user => ({ ...user, total: user.postsCount, percent: +((user.postsCount/metric.postsMetric.totalPosts())*100).toFixed(2) }));
    case TopUserActivityTypes.COMMENTS:
      return metric.usersMetric.sortByCommentsCount().slice(0, 10)
        .map(user => ({ ...user, total: user.commentsCount, percent: +((user.commentsCount/metric.postsMetric.totalComments())*100).toFixed(2) }));
    case TopUserActivityTypes.POSTS_SHARES:
      return metric.usersMetric.sortByPostsSharesCount().slice(0, 10)
        .map(user => ({ ...user, total: user.postsSharesCount, percent: +((user.postsSharesCount/metric.postsMetric.totalShares())*100).toFixed(2) }));
    case TopUserActivityTypes.POSTS_LIKES:
    default:
      return metric.usersMetric.sortByPostsLikesCount().slice(0, 10)
        .map(user => ({ ...user, total: user.postsLikesCount, percent: +((user.postsLikesCount/metric.postsMetric.totalLikes())*100).toFixed(2) }));
  }
}

const generateTitle = (type: TopUserActivityType): { title: string, subTitle: string } => {
  switch (type) {
    case TopUserActivityTypes.SCORE:
      return { title: 'Top User Activity by Score', subTitle: 'Top 10 user activity by score' };
    case TopUserActivityTypes.POSTS:
      return { title: 'Top User Activity by Posts', subTitle: 'Top 10 user activity by number of posts' };
    case TopUserActivityTypes.COMMENTS:
      return { title: 'Top User Activity by Comments', subTitle: 'Top 10 user activity by number of comments' };
    case TopUserActivityTypes.POSTS_LIKES:
      return { title: 'Top User Activity by Posts Likes', subTitle: 'Top 10 user activity by number of likes received on posts' };
    case TopUserActivityTypes.POSTS_SHARES:
      return { title: 'Top User Activity by Posts Shares', subTitle: 'Top 10 user activity by number of posts shares' };
    default:
      return { title: 'Top User Activity', subTitle: 'Top 10 user activity' };
  }
}

class TopUserActivity extends React.Component {

  props: {
    metric: TimeRangeMetric,
    type: TopUserActivityType,
  }

  render() {
    const { metric, type } = this.props;

    return (
      <Card title={generateTitle(type).title}>
        <p>{generateTitle(type).subTitle}, time range {timeRangeToString(metric.dateStart, metric.dateEnd)}.</p>

        <ul className="list-group">
          {getUsers(metric, type).filter(user => user.total > 0).map((user, index) => {
            const key = uuid.v4();

            switch (index) {
              case 0:
                return (
                  <li key={key} className="list-group-item">
                    <div className="col-12" style={{ margin: '0 -15px' }}>
                      {user.picture ? <img alt="user pic" src={user.picture} className="mr-1 mb-1" style={{ float: 'left', width: '50px' }} /> : ''}
                      <a href={user.url} target="_blank"><h4>{user.name}</h4></a>
                      <span>Total {type.toLowerCase()} {user.total} - {user.percent ? `${user.percent}%` : ''}</span>
                    </div>
                  </li>
                );
              case 1:
                return (
                  <li key={key} className="list-group-item">
                    <div className="col-12" style={{ margin: '0 -15px' }}>
                      {user.picture ? <img alt="user pic" src={user.picture} className="mr-1 mb-1" style={{ float: 'left', width: '45px' }} /> : ''}
                      <a href={user.url} target="_blank"><h5>{user.name}</h5></a>
                      <span>Total {type.toLowerCase()} {user.total} - {user.percent ? `${user.percent}%` : ''}</span>
                    </div>
                  </li>
                );
              case 2:
                return (
                  <li key={key} className="list-group-item">
                    <div className="col-12" style={{ margin: '0 -15px' }}>
                      {user.picture ? <img alt="user pic" src={user.picture} className="mr-1 mb-1" style={{ float: 'left', width: '40px' }} /> : ''}
                      <a href={user.url} target="_blank"><h6>{user.name}</h6></a>
                      <span>Total {type.toLowerCase()} {user.total} - {user.percent ? `${user.percent}%` : ''}</span>
                    </div>
                  </li>
                );
              default:
                return (
                  <li key={key} className="list-group-item">
                    <a href={user.url} target="_blank">{user.name}</a>: {user.total} - {user.percent ? `${user.percent}%` : ''}
                  </li>
                );
            }
          })}
        </ul>
      </Card>
    );
  }
}

export default TopUserActivity;