diff --git a/src/components/todoStuff/todoBoard.js b/src/components/todoStuff/todoBoard.js new file mode 100644 index 0000000..36d0abd --- /dev/null +++ b/src/components/todoStuff/todoBoard.js @@ -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 ( +
+
+ {Object.keys(columns).map((key) => { + const category = columns[key] + return ( +
+
{category.name}
+ {cards.map((card, i) => { + if (card.state === key) { + // TODO: determine if clickable here + return ( + + ) + } else { + return null + } + })} +
+ ) + })} +
+
+ ) +} diff --git a/src/components/todoStuff/todoBoard.module.css b/src/components/todoStuff/todoBoard.module.css new file mode 100644 index 0000000..7e603fa --- /dev/null +++ b/src/components/todoStuff/todoBoard.module.css @@ -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; +} diff --git a/src/components/todoStuff/todoRow.js b/src/components/todoStuff/todoRow.js new file mode 100644 index 0000000..6714428 --- /dev/null +++ b/src/components/todoStuff/todoRow.js @@ -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 ( +
+
{`#${id}`}
+
{name}
+
+
+ {categories[category].name} +
+
+
{`Votes: ${votes.length}`}
+
+ ) +} diff --git a/src/components/todoStuff/todoRow.module.css b/src/components/todoStuff/todoRow.module.css new file mode 100644 index 0000000..18af760 --- /dev/null +++ b/src/components/todoStuff/todoRow.module.css @@ -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; +} diff --git a/src/components/todoStuff/todos.js b/src/components/todoStuff/todos.js new file mode 100644 index 0000000..27956bf --- /dev/null +++ b/src/components/todoStuff/todos.js @@ -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 + } + + return ( +
+ + +
+ ) +}