bubbles-helper.js

import { useEffect, useState } from 'react'
import styled from 'styled-components'
import bucketBuilder from './bucket-builder'
import Bubbles from './bubbles'

import { PATH_BUBBLES } from '../../../utility/constants/path'
import { useBubblesApi } from '../../../hooks/useBubblesApi'

export function useBubbles() {
  const [data, error, loading] = useBubblesApi({ path: PATH_BUBBLES })
  const [bubbles, setBubbles] = useState(null)

  useEffect(() => {
    if (data) {
      const result = bucketBuilder(data)
      setBubbles(result)
    }
  }, [data])

  return [bubbles, error, loading]
}

export function renderBubbles(buckets, level = 0) {
  const domNodes = []

  if (buckets.length === 0) return null

  Object.entries(buckets).map(([key, bucket]) => {
    let childrens = []

    if (Object.keys(bucket).length > 1) {
      const filteredBuckets = Object.entries(bucket).filter(
        ([key]) => !['items', '_count'].includes(key)
      )
      childrens = renderBubbles(Object.fromEntries(filteredBuckets), level + 1)
    }

    if (bucket._count > 0) {
      let bubbles = <Bubbles bubbles={bucket.items}>{childrens}</Bubbles>

      bubbles = [0, 1, 2].includes(level) ? (
        <StyledBucket
          keyName={key}
          level={level}
          bubbles={bubbles}
        ></StyledBucket>
      ) : (
        <h3>click here to see sub items</h3>
      )

      domNodes.push(bubbles)
    }
  })

  return domNodes
}

function Bucket({ keyName, level, bubbles, className }) {
  const Title = `h${level + 2}`
  return (
    <div className={`bucket ${className}`} key={keyName}>
      <div className="bucket-header">
        <Title className="title">{keyName}</Title>
      </div>
      <div className="bucket-content">{bubbles}</div>
    </div>
  )
}

const StyledBucket = styled(Bucket)`
  border: 1px solid #cfcfcf;
  border-radius: 8px;
  margin: 12px;
  padding: 0 4px 4px;
  .bucket {
    margin: 2px 0;
  }

  .bucket-header {
    h2.title,
    h3.title,
    h4.title,
    h5.title {
      padding-left: 12px;
    }
  }
  .bucket-content {
    .created-on {
      font-size: 0.7rem;
      padding-top: 4px;
    }

    .due-on {
      font-size: 0.8rem;
      width: 50px;
      margin-left: 12px;
      text-align: center;
      .due-on--text {
        font-size: 0.8rem;
        padding-top: 2px;
      }
    }
  }
`