Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Challenge #4

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
13,461 changes: 13,461 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"@types/react-dom": "16.8.4",
"@types/react-redux": "^7.0.8",
"@types/react-router-dom": "^4.3.2",
"@types/shortid": "0.0.29",
"@types/styled-components": "^4.1.14",
"color": "^3.1.1",
"react": "^16.10.1",
Expand All @@ -20,6 +21,7 @@
"redux": "^4.0.1",
"redux-devtools-extension": "latest",
"redux-thunk": "^2.3.0",
"shortid": "^2.2.15",
"styled-components": "^4.2.0",
"typescript": "3.4.5"
},
Expand Down
2 changes: 0 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import React from "react";
import styled from "styled-components";
import { __COLORS } from "./layout/Theme";
import MyImage, { AssetType } from "./views/Figure";
import MainRouter from "./routes/MainRouter";
import { BounceIn } from "./layout/UI/Animations/BounceIn";

const Container = styled.div`
display: flex;
Expand Down
36 changes: 36 additions & 0 deletions src/components/AddTodoForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React, { useState, ChangeEvent, FormEvent } from "react";
import { AddTodo } from "../model/Todo";
import styled from "styled-components";

interface AddTodoFormProps {
addTodo: AddTodo;
}

const CenteredDiv = styled.div`
text-align: center;
`;

export const AddTodoForm: React.FC<AddTodoFormProps> = ({ addTodo }) => {
const [newTodo, setNewTodo] = useState<string>("");

const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
setNewTodo(e.target.value);
};

const handleSubmit = (e: FormEvent<HTMLButtonElement>) => {
e.preventDefault();
addTodo({
userId: "manuelgr",
title: newTodo,
completed: false,
});
setNewTodo("");
};

return <CenteredDiv>
<form>
<input type="text" value={newTodo} onChange={handleChange} />
<button type="submit" onClick={handleSubmit}>Add Todo</button>
</form>
</CenteredDiv>
}
161 changes: 103 additions & 58 deletions src/components/AxelraTrello.tsx
Original file line number Diff line number Diff line change
@@ -1,90 +1,135 @@
import React, { Component, useEffect, useState } from "react";
import React, { useEffect, useState } from "react";
import styled from "styled-components";
import { __ALERTS, __COLORS, __GRAY_SCALE } from "../layout/Theme";
import { __GRAY_SCALE } from "../layout/Theme";
import { getDomain } from "../helpers/Domain";
import { HTTP_OPTIONS, PROTOCOL_METHOD } from "../helpers/FetchOptions";
import { Todo, ToggleTodo, AddTodo, DeleteTodo, ChangeStatus } from "../model/Todo"
import { TodoList } from "./TodoList"
import { AddTodoForm } from "./AddTodoForm"

const Container = styled.div`
border: 1px solid ${__GRAY_SCALE._200};
padding: 1em;
border-radius: 6px;
`;

const Colors = styled.div`
display: flex;
flex-wrap: wrap;
`;

const Title = styled.h1`
font-size: 32px;
`;

const Color = styled.div<{ background: __COLORS | __GRAY_SCALE | __ALERTS }>`
&:first-of-type {
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
export const AxelraTrello = () => {
const TodoArray: Array<Todo> = [];

const [initalFetchComplete, setInitalFetchComplete] = useState<boolean>(false);
const [todos, setTodos] = useState<Array<Todo>>(TodoArray);

const toggleTodo: ToggleTodo = selectedTodo => {
const newTodos = todos.map(todo => {
if (todo === selectedTodo) {
return {
...todo,
completed: !todo.completed
}
}
return todo;
})
setTodos(newTodos);
}
&:last-of-type {
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;

const addTodo: AddTodo = newTodo => {
fetch(`${getDomain()}/addtodo`, { ...HTTP_OPTIONS(PROTOCOL_METHOD.POST), body: JSON.stringify(newTodo) })
.then(response => response.json())
.then(response => {
if (!response.success) {
console.error(response);
}
fetchListItems();
})
.catch(error => {
console.error("Some error occured", error);
});
}
padding: 1.2rem;
flex: 1;
background: ${props => props.background};
`;

export const AxelraTrello = () => {
const [response, setResponse] = useState(null);
const deleteTodo: DeleteTodo = todoid => {
fetch(`${getDomain()}/deletetodo`, { ...HTTP_OPTIONS(PROTOCOL_METHOD.DELETE), body: todoid })
.then(response => response.json())
.then(response => {
if (!response.success) {
console.error(response);
}
})
.catch(error => {
console.error("Some error occured", error);
});
todos.splice(todos.findIndex(todo => todo._id === todoid), 1)
setTodos([...todos]);
}

useEffect(() => {
fetch(`${getDomain()}/hello`, HTTP_OPTIONS(PROTOCOL_METHOD.GET))
const changeStatus: ChangeStatus = todoid => {
fetch(`${getDomain()}/changestatus`, { ...HTTP_OPTIONS(PROTOCOL_METHOD.PUT), body: todoid })
.then(response => response.json())
.then(response => {
if (!response.success) {
console.error(response);
}
})
.catch(error => {
console.error("Some error occured", error);
});
let index = todos.findIndex(todo => todo._id === todoid);
todos[index].completed = !todos[index].completed;
setTodos([...todos]);
}

const fetchListItems = () => {
fetch(`${getDomain()}/getalltodos`, HTTP_OPTIONS(PROTOCOL_METHOD.GET))
.then(response => response.json())
.then(response => {
if (response.success) {
setResponse(response.data.message);
setTodos(response.data.dbQueryResult);
setInitalFetchComplete(true);
}
})
.catch(error => {
console.error("Some error occured", error);
});
}, []);
}

useEffect(fetchListItems, []);
return (
<>
<Title>Axelra Trello Challenge</Title>
{response ? <p>{response}</p> : <p>Loading...</p>}
<Container>
<h1>Heading H1</h1>
<h2>Heading H2</h2>
<h3>Heading H3</h3>
<h4>Heading H4</h4>
<h5>Heading H5</h5>
<p>
Lorem Ipsum is simply dummy text of the printing and typesetting
industry. Lorem Ipsum has been the industry's standard dummy text ever
since the 1500s, when an unknown printer took a galley of type and
scrambled it to make a type specimen book. It has survived not only
five centuries,{" "}
</p>
<h2>Colors Palette </h2>
<Colors>
<Color background={__COLORS.PRIMARY} />
<Color background={__COLORS.SECONDARY} />
<Color background={__COLORS.TERTRIARY} />
<Color background={__COLORS.FOURTH} />
</Colors>
<h2>Gray Scale</h2>
<Colors>
<Color background={__GRAY_SCALE._100} />
<Color background={__GRAY_SCALE._200} />
<Color background={__GRAY_SCALE._300} />
<Color background={__GRAY_SCALE._400} />
<Color background={__GRAY_SCALE._500} />
<Color background={__GRAY_SCALE._600} />
<Color background={__GRAY_SCALE._700} />
<Color background={__GRAY_SCALE._800} />
<Color background={__GRAY_SCALE._900} />
</Colors>
</Container>
{
initalFetchComplete ?
<div>
<Container>
<h1>In Progress</h1>
<React.Fragment>
<TodoList
todos={todos}
toggleTodo={toggleTodo}
deleteTodo={deleteTodo}
changeStatus={changeStatus}
todoscompleted={false}
/>
<AddTodoForm addTodo={addTodo} />
</React.Fragment>
</Container>
<Container>
<h1>Done</h1>
<React.Fragment>
<TodoList
todos={todos}
toggleTodo={toggleTodo}
deleteTodo={deleteTodo}
changeStatus={changeStatus}
todoscompleted={true}
/>
</React.Fragment>
</Container>
</div> :
<p>Loading...</p>
}
</>
);
};
Expand Down
42 changes: 42 additions & 0 deletions src/components/TodoList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from "react"
import { TodoListItem } from "./TodoListItem"
import { Todo, ToggleTodo, DeleteTodo, ChangeStatus } from "../model/Todo"
import styled from "styled-components";

interface TodoListProps {
todos: Array<Todo>;
toggleTodo: ToggleTodo;
deleteTodo: DeleteTodo;
changeStatus: ChangeStatus;
todoscompleted: boolean;
}

const TodoUnorderedList = styled.ul`
font-size: 100%;
list-style: none;
width: 100%;
overflow-x: hidden;
margin-top: 2rem;
`;

export const TodoList: React.FC<TodoListProps> = ({
todos,
toggleTodo,
deleteTodo,
changeStatus,
todoscompleted
}) => {
return <TodoUnorderedList>
{todos
.filter(todo => todo.completed === todoscompleted)
.map(todo => {
return <TodoListItem
key={todo._id}
todo={todo}
toggleTodo={toggleTodo}
deleteTodo={deleteTodo}
changeStatus={changeStatus}
/>
})}
</TodoUnorderedList>
}
57 changes: 57 additions & 0 deletions src/components/TodoListItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React, { FormEvent } from "react";
import { Todo, ToggleTodo, DeleteTodo, ChangeStatus } from '../model/Todo'
import styled from "styled-components";

interface TodoListItemProps {
todo: Todo;
toggleTodo: ToggleTodo;
deleteTodo: DeleteTodo;
changeStatus: ChangeStatus;
}

const DeleteButton = styled.button`
background-image: url('https://cdn2.iconfinder.com/data/icons/round-interface-1/217/50-512.png');
background-size: 16px 16px;
height: 16px;
width: 16px;
border-radius: 50%;
border: 0;
`;

const ChangeButtonUpDown = styled.button`
background-image: url('https://cdn3.iconfinder.com/data/icons/pyconic-icons-1-2/512/arrow-up-down-2-512.png');
background-size: 16px 16px;
height: 16px;
width: 16px;
border-radius: 50%;
border: 0;
`;

export const TodoListItem: React.FC<TodoListItemProps> = ({
todo,
deleteTodo,
changeStatus,
}) => {
const handleSubmitChange = (e: FormEvent<HTMLButtonElement>) => {
e.preventDefault();
changeStatus(todo._id);
};

const handleSubmitDelete = (e: FormEvent<HTMLButtonElement>) => {
e.preventDefault();
deleteTodo(todo._id);
};

return (
<li>
<label>
<ChangeButtonUpDown type="submit" onClick={handleSubmitChange}></ChangeButtonUpDown>
&emsp;
<DeleteButton type="submit" onClick={handleSubmitDelete}></DeleteButton>
&emsp;
{todo.title}
</label>
</li>

);
};
13 changes: 12 additions & 1 deletion src/model/Todo.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
// Example of a simple type
export type Todo = {
userId: string;
id: number;
_id: string;
title: string;
completed: boolean;
};

export type TodoAdd = {
userId: string;
title: string;
completed: boolean;
};

export type ToggleTodo = (selectedTodo: Todo) => void;
export type AddTodo = (newTodo: TodoAdd) => void;
export type DeleteTodo = (todoId: string) => void;
export type ChangeStatus = (todoId: string) => void;