Added missing files

This commit is contained in:
mrfry 2020-11-28 16:49:52 +01:00
parent 4f12a18e28
commit db5aad0f8c
5 changed files with 253 additions and 0 deletions

View file

@ -0,0 +1,49 @@
import React from 'react'
import TodoCard from './todoCard.js'
import styles from './todoBoard.module.css'
export default function TodoBoard(props) {
const { columns, cards, userId, categories, onCardClick } = props
const clickableTypes = Object.keys(columns).reduce((acc, key) => {
const col = columns[key]
if (col.clickable) {
acc.push(key)
}
return acc
}, [])
return (
<div className={styles.tableContainer}>
<div className={styles.table}>
{Object.keys(columns).map((key) => {
const category = columns[key]
return (
<div className={styles.tableCol} key={key}>
<div className={styles.categoryName}>{category.name}</div>
{cards.map((card, i) => {
if (card.state === key) {
// TODO: determine if clickable here
return (
<TodoCard
key={i}
cardData={card}
userId={userId}
categories={categories}
onClick={onCardClick}
clickable={clickableTypes.includes(key)}
/>
)
} else {
return null
}
})}
</div>
)
})}
</div>
</div>
)
}

View file

@ -0,0 +1,23 @@
.tableContainer {
overflow-y: hidden;
overflow-x: auto;
margin: 5px 0px;
}
.table {
display: flex;
min-width: 800px;
}
.categoryName {
text-align: center;
margin: 5px 0px;
font-size: 16px;
font-weight: bold;
color: white;
white-space: nowrap;
}
.tableCol {
flex: 1;
}

View file

@ -0,0 +1,34 @@
import React from 'react'
import styles from './todoRow.module.css'
export default function TodoRow(props) {
const { categories, userId } = props
const { name, description, category, votes, id } = props.rowData
const voted = votes.includes(userId)
return (
<div
className={`${styles.row} ${voted && styles.voted}`}
title={description}
>
<div className={styles.id}>{`#${id}`}</div>
<div className={styles.description}>{name}</div>
<div className={styles.catName}>
<div
style={{
wordBreak: 'break-all',
fontSize: '10px',
backgroundColor: categories[category].color,
color: 'white',
borderRadius: '2px',
padding: '0px 2px',
}}
>
{categories[category].name}
</div>
</div>
<div className={styles.votes}>{`Votes: ${votes.length}`}</div>
</div>
)
}

View file

@ -0,0 +1,40 @@
.row {
display: flex;
border: 2px solid #99f;
border-radius: 2px;
padding: 5px;
margin: 6px 3px;
}
.row > div {
margin: 0px 5px;
}
.id {
flex: 0 20px;
margin: 0px 3px;
color: #999;
}
.description {
flex: 1;
word-break: normal;
font-size: 14px;
color: white;
}
.votes {
}
.voted {
border: 2px solid #cf9;
}
.catName {
display: flex;
}
.category {
word-break: break-all;
font-size: 10px;
}

View file

@ -0,0 +1,107 @@
import React, { useState, useEffect } from 'react'
import LoadingIndicator from '../LoadingIndicator.js'
import TodoBoard from './todoBoard.js'
import TodoTable from './todoTable.js'
import constants from '../../constants.json'
const byVotes = (a, b) => {
return b.votes.length - a.votes.length
}
export default function Todos() {
const [loaded, setLoaded] = useState(false)
const [columns, setColumns] = useState(null)
const [boardCards, setBoardCards] = useState(null)
const [tables, setTables] = useState(null)
const [tableCards, setTableCards] = useState(null)
const [categories, setCategories] = useState(null)
const [userId, setUserId] = useState(null)
useEffect(() => {
console.info('Fetching todos')
fetch(`${constants.apiUrl}todos`, {
credentials: 'include',
})
.then((resp) => {
return resp.json()
})
.then((data) => {
setTodos(data)
})
}, [])
const setTodos = (data) => {
setCategories(data.todos.categories)
setUserId(data.userId)
let bCards = []
let tCards = []
data.todos.cards.forEach((card) => {
if (data.todos.columns[card.state].type === 'table') {
tCards.push(card)
} else {
bCards.push(card)
}
})
setTableCards(tCards.sort(byVotes))
setBoardCards(bCards.sort(byVotes))
let cols = {}
let tables = {}
Object.keys(data.todos.columns).forEach((key) => {
const col = data.todos.columns[key]
if (col.type !== 'table') {
cols = {
...cols,
[key]: col,
}
} else {
tables = {
...tables,
[key]: col,
}
}
})
setColumns(cols)
setTables(tables)
setLoaded(true)
}
const onCardClick = (id) => {
fetch(`${constants.apiUrl}todos?id=${id}`, {
credentials: 'include',
})
.then((resp) => {
return resp.json()
})
.then((data) => {
setTodos(data)
})
}
if (!loaded) {
return <LoadingIndicator />
}
return (
<div>
<TodoBoard
columns={columns}
cards={boardCards}
userId={userId}
categories={categories}
onCardClick={onCardClick}
/>
<TodoTable
tables={tables}
cards={tableCards}
userId={userId}
categories={categories}
/>
</div>
)
}