mirror of
https://github.com/usatiuk/ustk-todolist.git
synced 2025-10-28 23:57:49 +01:00
design changes
This commit is contained in:
5432
package-lock.json
generated
5432
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@@ -3,8 +3,8 @@
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.0-13",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.1.0-10",
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.0-14",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.1.0-11",
|
||||
"@fortawesome/react-fontawesome": "0.1.0-10",
|
||||
"normalize.css": "^8.0.0",
|
||||
"prop-types": "^15.6.1",
|
||||
@@ -12,9 +12,9 @@
|
||||
"react-dom": "^16.4.0",
|
||||
"react-redux": "^5.0.7",
|
||||
"react-scripts": "1.1.4",
|
||||
"react-spring": "^5.3.3",
|
||||
"react-spring": "^5.3.7",
|
||||
"redux": "^4.0.0",
|
||||
"redux-thunk": "^2.2.0"
|
||||
"redux-thunk": "^2.3.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
@@ -26,7 +26,7 @@
|
||||
"eslint-config-airbnb": "^16.1.0",
|
||||
"eslint-config-prettier": "^2.9.0",
|
||||
"eslint-plugin-import": "^2.12.0",
|
||||
"eslint-plugin-jest": "^21.16.0",
|
||||
"eslint-plugin-jest": "^21.17.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.0.3",
|
||||
"eslint-plugin-react": "^7.8.2",
|
||||
"prettier-eslint": "^8.8.1"
|
||||
|
||||
140
src/App.css
140
src/App.css
@@ -3,10 +3,49 @@ body {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
#header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#lists {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
#listactions {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 0.2rem 0.1rem;
|
||||
}
|
||||
|
||||
#listactions button {
|
||||
font-size: 0.9rem;
|
||||
color: #555555;
|
||||
background: none;
|
||||
border: none;
|
||||
margin: 0.1rem 0.3rem;
|
||||
padding: 0.3rem 0.7em;
|
||||
}
|
||||
|
||||
#listactions button:hover {
|
||||
transition: 0.1s ease-in-out;
|
||||
color: #222222;
|
||||
}
|
||||
|
||||
#filters {
|
||||
margin-right: 0.75rem;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
#listselector {
|
||||
margin-left: 0.2rem;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
#listselector select {
|
||||
font-size: 1.75rem;
|
||||
font-size: 1.5rem;
|
||||
font-weight: 500;
|
||||
margin: 1rem 1.5rem;
|
||||
outline: none;
|
||||
border: none;
|
||||
background: #fff;
|
||||
@@ -27,8 +66,12 @@ body {
|
||||
}
|
||||
|
||||
#inputs {
|
||||
border-top: 1px solid #888888;
|
||||
border-bottom: 1px solid #888888;
|
||||
transition: 0.4s ease-in-out;
|
||||
box-shadow: 0 3px 5px rgba(0, 0, 0, 0.1);
|
||||
display: flex;
|
||||
height: 2rem;
|
||||
height: 2.5rem;
|
||||
}
|
||||
|
||||
#input {
|
||||
@@ -40,49 +83,31 @@ body {
|
||||
padding: 0;
|
||||
padding-left: 1rem;
|
||||
height: 100%;
|
||||
max-width: 80%;
|
||||
line-height: 100%;
|
||||
border: none;
|
||||
border-top: 1px solid #888888;
|
||||
border-bottom: 1px solid #888888;
|
||||
}
|
||||
|
||||
#add {
|
||||
font-size: 0.9rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 700;
|
||||
flex-grow: 1;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
width: 5rem;
|
||||
max-width: 20%;
|
||||
max-width: 5rem;
|
||||
background-color: white;
|
||||
border: none;
|
||||
border-top: 1px solid #888888;
|
||||
border-bottom: 1px solid #888888;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
font-weight: 500;
|
||||
max-height: 7rem;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
font-size: 1rem;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#inputs.no-border input,
|
||||
#inputs.no-border button {
|
||||
#inputs.no-border {
|
||||
transition: 0.4s ease-in-out;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
li:first-child .delete,
|
||||
li:first-child .item {
|
||||
li:first-child .edit,
|
||||
li:first-child .save,
|
||||
li:first-child .todo {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
@@ -92,6 +117,7 @@ li:first-child .item {
|
||||
}
|
||||
|
||||
li button {
|
||||
outline: none;
|
||||
text-align: left;
|
||||
flex-shrink: 0;
|
||||
box-sizing: border-box;
|
||||
@@ -100,13 +126,17 @@ li button {
|
||||
border: none;
|
||||
border-top: 1px solid #dddddd;
|
||||
background: none;
|
||||
max-width: 2rem;
|
||||
width: 2rem;
|
||||
font-size: 1rem;
|
||||
transition: 0.3s ease-in-out;
|
||||
transition: 0.4s ease-in-out;
|
||||
overflow: hidden;
|
||||
box-shadow: inset -3px 0 6px -3px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
li button.todo {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.delete {
|
||||
background-color: pink;
|
||||
}
|
||||
@@ -119,63 +149,61 @@ li button {
|
||||
background-color: lightgreen;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
height: 60px;
|
||||
width: 100%;
|
||||
font-weight: 500;
|
||||
overflow: hidden;
|
||||
font-size: 1rem;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.todo {
|
||||
text-align: left;
|
||||
box-sizing: border-box;
|
||||
word-wrap: break-word;
|
||||
max-width: 100%;
|
||||
width: 100%;
|
||||
padding: 0.5rem;
|
||||
border-top: 1px solid #dddddd;
|
||||
flex-grow: 2;
|
||||
flex-shrink: 1;
|
||||
transition: 0.1s ease-in-out;
|
||||
transition: 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.todo--input {
|
||||
resize: vertical;
|
||||
resize: none;
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
word-wrap: break-word;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-height: 100%;
|
||||
transition: 0.1s ease-in-out;
|
||||
transition: 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.disabled {
|
||||
max-width: 0;
|
||||
width: 0;
|
||||
padding: 0.5rem 0;
|
||||
}
|
||||
|
||||
.item-create {
|
||||
animation: 0.4s create;
|
||||
}
|
||||
|
||||
.item-collapse {
|
||||
animation: 0.4s collapse;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.filters {
|
||||
align-self: center;
|
||||
margin-right: 2rem;
|
||||
}
|
||||
|
||||
.filter {
|
||||
margin: 0.1rem;
|
||||
padding: 0.5rem;
|
||||
color: gray;
|
||||
color: #555555;
|
||||
border: none;
|
||||
background: none;
|
||||
transition: 0.1s ease-in-out;
|
||||
font-size: 0.9rem;
|
||||
transition: 0.3s ease-in-out;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.filter--active {
|
||||
color: black;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
@@ -140,7 +140,7 @@ export function fetchTodos(list) {
|
||||
|
||||
export const ADD_LIST = 'ADD_LIST';
|
||||
export const REMOVE_LIST = 'REMOVE_LIST';
|
||||
export const EDIT_LIST = 'EDIT_LIST';
|
||||
export const EDIT_LIST_NAME = 'EDIT_LIST_NAME';
|
||||
export const RECIEVE_LISTS = 'RECIEVE_LISTS';
|
||||
export const REQUEST_LISTS = 'REQUEST_LISTS';
|
||||
export const INVALIDATE_LISTS = 'INVALIDATE_LISTS';
|
||||
@@ -212,8 +212,8 @@ export function removeList(id) {
|
||||
};
|
||||
}
|
||||
|
||||
function editListInState(id, list) {
|
||||
return { type: EDIT_LIST, id, list };
|
||||
function editListNameInState(id, name) {
|
||||
return { type: EDIT_LIST_NAME, id, name };
|
||||
}
|
||||
|
||||
export function editList(id, name) {
|
||||
@@ -228,8 +228,7 @@ export function editList(id, name) {
|
||||
});
|
||||
const json = await response.json();
|
||||
if (json.success) {
|
||||
const list = json.data;
|
||||
dispatch(editListInState(id, list));
|
||||
dispatch(editListNameInState(id, name));
|
||||
}
|
||||
dispatch(validateLists());
|
||||
};
|
||||
|
||||
@@ -5,11 +5,9 @@ import ListsContainer from '../containers/ListsContainer';
|
||||
|
||||
export default function Header() {
|
||||
return (
|
||||
<div className="header">
|
||||
<div id="listselector">
|
||||
<ListsContainer />
|
||||
</div>
|
||||
<div className="filters">
|
||||
<div id="header">
|
||||
<ListsContainer />
|
||||
<div id="filters">
|
||||
<FilterLink filter={VisibilityFilters.SHOW_ALL}>all</FilterLink>
|
||||
<FilterLink filter={VisibilityFilters.SHOW_ACTIVE}>active</FilterLink>
|
||||
<FilterLink filter={VisibilityFilters.SHOW_COMPLETED}>completed</FilterLink>
|
||||
|
||||
@@ -1,11 +1,22 @@
|
||||
import { faTrash, faEdit, faPlus } from '@fortawesome/free-solid-svg-icons';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
export default function ListActions({ addList, removeList, list }) {
|
||||
export default function ListActions({
|
||||
addList, removeList, editList, list,
|
||||
}) {
|
||||
return (
|
||||
<div>
|
||||
<button onClick={() => addList(prompt('List name?'))}>Add</button>
|
||||
<button onClick={() => removeList(list)}>Remove</button>
|
||||
<div id="listactions">
|
||||
<button onClick={() => addList(prompt('List name?'))}>
|
||||
<FontAwesomeIcon icon={faPlus} />
|
||||
</button>
|
||||
<button onClick={() => removeList(list)}>
|
||||
<FontAwesomeIcon icon={faTrash} />
|
||||
</button>
|
||||
<button onClick={() => editList(list, prompt('List name?'))}>
|
||||
<FontAwesomeIcon icon={faEdit} />
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -17,5 +28,6 @@ ListActions.defaultProps = {
|
||||
ListActions.propTypes = {
|
||||
addList: PropTypes.func.isRequired,
|
||||
removeList: PropTypes.func.isRequired,
|
||||
editList: PropTypes.func.isRequired,
|
||||
list: PropTypes.string,
|
||||
};
|
||||
|
||||
@@ -4,13 +4,16 @@ import Selector from './Selector';
|
||||
import ListActions from './ListActions';
|
||||
|
||||
export default function Lists({
|
||||
list, lists, onChange, addList, removeList,
|
||||
list, lists, onChange, addList, removeList, editList,
|
||||
}) {
|
||||
const selectorProps = { list, lists, onChange };
|
||||
const actionsProps = { addList, removeList, list };
|
||||
const actionsProps = {
|
||||
addList, removeList, editList, list,
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<Selector {...selectorProps} /> <ListActions {...actionsProps} />
|
||||
<div id="lists">
|
||||
<ListActions {...actionsProps} />
|
||||
<Selector {...selectorProps} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -27,4 +30,5 @@ Lists.propTypes = {
|
||||
onChange: PropTypes.func.isRequired,
|
||||
addList: PropTypes.func.isRequired,
|
||||
removeList: PropTypes.func.isRequired,
|
||||
editList: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
@@ -8,7 +8,7 @@ export default function Selector(props) {
|
||||
</option>
|
||||
));
|
||||
return (
|
||||
<div>
|
||||
<div id="listselector">
|
||||
<select value={props.list} onChange={e => props.onChange(e.target.value)}>
|
||||
{lists}
|
||||
</select>
|
||||
|
||||
@@ -5,26 +5,26 @@ import { Transition } from 'react-spring';
|
||||
import Todo from './Todo';
|
||||
|
||||
export default function TodosContainer(props) {
|
||||
const todos = props.todos.map(todo => styles => (
|
||||
<Todo
|
||||
key={todo.id}
|
||||
todo={todo}
|
||||
style={styles}
|
||||
toggleTodo={() => props.toggleTodo(todo.id)}
|
||||
removeTodo={() => props.removeTodo(todo.id)}
|
||||
editTodo={text => props.editTodo(todo.id, text)}
|
||||
/>
|
||||
));
|
||||
return (
|
||||
<ul id="list">
|
||||
<Transition
|
||||
native
|
||||
keys={props.todos.map(todo => todo.id)}
|
||||
from={{ maxHeight: 0 }}
|
||||
enter={{ maxHeight: 100 }}
|
||||
leave={{ maxHeight: 0 }}
|
||||
items={props.todos}
|
||||
keys={todo => todo.id}
|
||||
from={todo => ({ height: 0, borderColor: '#ffffff', opacity: 0.9 })}
|
||||
enter={todo => ({ height: 60, borderColor: '#dddddd', opacity: 1 })}
|
||||
leave={todo => ({ height: 0, borderColor: '#ffffff', opacity: 0.5 })}
|
||||
>
|
||||
{todos}
|
||||
{props.todos.map(todo => styles => (
|
||||
<Todo
|
||||
key={todo.id}
|
||||
todo={todo}
|
||||
style={styles}
|
||||
toggleTodo={() => props.toggleTodo(todo.id)}
|
||||
removeTodo={() => props.removeTodo(todo.id)}
|
||||
editTodo={text => props.editTodo(todo.id, text)}
|
||||
/>
|
||||
))}
|
||||
</Transition>
|
||||
</ul>
|
||||
);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { connect } from 'react-redux';
|
||||
import Lists from '../components/Lists';
|
||||
import { changeList, removeList, addList } from '../actions';
|
||||
import { changeList, removeList, addList, editList } from '../actions';
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
@@ -15,6 +15,7 @@ function mapDispatchToProps(dispatch) {
|
||||
onChange: list => dispatch(changeList(list)),
|
||||
addList: name => dispatch(addList(name)),
|
||||
removeList: id => dispatch(removeList(id)),
|
||||
editList: (id, name) => dispatch(editList(id, name)),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@ import {
|
||||
RECIEVE_LISTS,
|
||||
ADD_LIST,
|
||||
REMOVE_LIST,
|
||||
EDIT_LIST,
|
||||
EDIT_TODO,
|
||||
EDIT_LIST_NAME,
|
||||
} from '../actions';
|
||||
|
||||
import list from './list';
|
||||
@@ -51,10 +51,10 @@ export default function lists(
|
||||
lists: newLists,
|
||||
};
|
||||
}
|
||||
case EDIT_LIST: {
|
||||
case EDIT_LIST_NAME: {
|
||||
return {
|
||||
...state,
|
||||
lists: { ...state.lists, [action.id]: action.list },
|
||||
lists: { ...state.lists, [action.id]: { ...state.lists[action.id], name: action.name } },
|
||||
};
|
||||
}
|
||||
case INVALIDATE_LISTS:
|
||||
|
||||
Reference in New Issue
Block a user