Skip to content

Commit

Permalink
Add entry note editing
Browse files Browse the repository at this point in the history
  • Loading branch information
overshard committed Oct 12, 2019
1 parent e062021 commit 3ef84b8
Show file tree
Hide file tree
Showing 7 changed files with 265 additions and 120 deletions.
14 changes: 13 additions & 1 deletion components/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const reducer = (state, action) => {
timer: new Date(),
log: [
{
id: uuid(), // HACK: react-transition-group requires an id?
id: uuid(),
start: state.timer,
end: new Date(),
note: action.note,
Expand All @@ -62,6 +62,18 @@ const reducer = (state, action) => {
localForage.setItem("context", newState);
toast.success(strings.addedEntry);
return newState;
case "EDIT_LOG":
newState = {
...state,
log: [
...state.log.map(entry => {
return entry.id == action.entry.id ? action.entry : entry;
})
]
};
localForage.setItem("context", newState);
toast.success(strings.editedEntry);
return newState;
case "REMOVE_LOG":
newState = {
...state,
Expand Down
220 changes: 220 additions & 0 deletions components/entry.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
import React, { useState, useContext } from "react";
import styled from "styled-components";
import useForm from "react-hook-form";
import PropTypes from "prop-types";

import { timeString } from "../utils/time";
import { Context } from "../components/context";

const Entry = ({ entry, removeEntry }) => {
const { state, dispatch } = useContext(Context);
const { register, handleSubmit } = useForm();
const [edit, setEdit] = useState(false);

const onSubmit = data => {
console.log(data);
dispatch({
type: "EDIT_LOG",
entry: {
...entry,
note: data.note,
tags: data.note
.split(" ")
.filter(word => word.startsWith("#"))
.map(word => {
return word.toLowerCase();
})
}
});
setEdit(false);
};

return (
<EntryContainer>
{edit ? (
<EntryForm onSubmit={handleSubmit(onSubmit)}>
<EntryTime>{timeString(entry.end - entry.start)}</EntryTime>
<EntryNote>
<EntryNoteInput
name="note"
defaultValue={entry.note}
ref={register}
/>
</EntryNote>
<EntrySubmit type="submit"></EntrySubmit>
<EntryRemove onClick={() => removeEntry(entry.id)}>x</EntryRemove>
</EntryForm>
) : (
<>
<EntryTime>{timeString(entry.end - entry.start)}</EntryTime>
<EntryNote className={entry.note.length === 0 && "empty"}>
{entry.note}
{entry.tags.length > 0 && (
<small>
{entry.tags
.map(tag => {
return tag;
})
.join(", ")}
</small>
)}
</EntryNote>
<EntryEdit
onClick={() => {
setEdit(true);
}}
>
_
</EntryEdit>
<EntryRemove onClick={() => removeEntry(entry.id)}>x</EntryRemove>
</>
)}
</EntryContainer>
);
};

Entry.propTypes = {
entry: PropTypes.object,
removeEntry: PropTypes.func
};

export default Entry;

const EntryContainer = styled.div`
background-color: #ffffff;
color: black;
margin-bottom: 15px;
display: grid;
grid-template-columns: 150px 1fr 50px 50px;
align-items: center;
border-bottom: 1px solid ${props => props.theme.colors.four};
&.fade-appear,
&.fade-enter {
opacity: 0;
transform: translateX(-100px);
}
&.fade-appear-active,
&.fade-enter-active {
opacity: 1;
transform: translateX(0);
transition-duration: 250ms;
transition-property: opacity, transform;
}
&.fade-exit {
opacity: 1;
transform: translateX(0);
}
&.fade-exit-active {
opacity: 0;
transition-delay: 0ms !important;
transition-duration: 250ms;
transition-property: opacity, transform;
transform: translateX(100px);
}
@media (${props => props.theme.breakpoint}) {
grid-template-columns: 1fr 1fr;
grid-template-rows: auto auto auto;
text-align: center;
}
`;

const EntryForm = styled.form`
display: contents;
`;

const EntryNoteInput = styled.input`
border: none;
padding: 12px 0;
font-size: 1em;
width: 100%;
border-bottom: 2px solid ${props => props.theme.colors.three};
`;

const EntryTime = styled.div`
font-weight: bold;
font-size: 1.3em;
padding: 15px;
height: 100%;
background-color: ${props => props.theme.colors.four};
color: white;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
@media (${props => props.theme.breakpoint}) {
grid-column: 1 / span 2;
}
`;

const EntryNote = styled.div`
padding: 15px;
&.empty {
padding: 0;
}
& small {
display: block;
color: gray;
margin-top: 5px;
}
@media (${props => props.theme.breakpoint}) {
grid-column: 1 / span 2;
}
`;

const EntryEdit = styled.button`
font-size: 1.3em;
font-weight: bolder;
color: white;
cursor: pointer;
border: 0;
background: ${props => props.theme.colors.four};
margin: 0;
padding: 15px;
height: 100%;
@media (${props => props.theme.breakpoint}) {
padding: 5px;
}
`;

const EntrySubmit = styled.button`
font-size: 1.3em;
font-weight: bolder;
color: white;
cursor: pointer;
border: 0;
background: ${props => props.theme.colors.four};
margin: 0;
padding: 15px;
height: 100%;
@media (${props => props.theme.breakpoint}) {
padding: 5px;
}
`;

const EntryRemove = styled.button`
font-size: 1.3em;
font-weight: bolder;
color: white;
cursor: pointer;
border: 0;
background: ${props => props.theme.colors.five};
margin: 0;
padding: 15px;
height: 100%;
@media (${props => props.theme.breakpoint}) {
padding: 5px;
}
`;
2 changes: 2 additions & 0 deletions l10n/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ const strings = new LocalizedStrings({
en: {
loaded: "Loaded state from local storage.",
addedEntry: "You've added an entry.",
editedEntry: "You've edited an entry.",
deletedEntry: "You've deleted an entry.",
resetLog: "You've reset your log."
},
// None of this is accurate past this line, someone please help me translate...
jp: {
loaded: "ローカルストレージから状態をロードしました。",
addedEntry: "エントリを追加しました。",
editedEntry: "エントリを編集しました。",
deletedEntry: "エントリを削除しました。",
resetLog: "ログをリセットしました。"
}
Expand Down
5 changes: 5 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"next-offline": "^4.0.2",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-hook-form": "^3.23.18",
"react-localization": "^1.0.14",
"react-toastify": "^5.3.2",
"react-transition-group": "^4.2.1",
Expand Down
8 changes: 7 additions & 1 deletion pages/_app.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class MyApp extends App {
}

export default MyApp;
// NOTE: Prevent renderblocking of Google WebFonts CSS by importing it here

const GlobalStyle = createGlobalStyle`
body {
font-family:
Expand All @@ -70,6 +70,12 @@ const GlobalStyle = createGlobalStyle`
text-shadow: rgba(0, 0, 0, .01) 0 0 1px;
text-rendering: optimizeLegibility;
}
input {
font-family:
-apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial,
sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}
`;

const Transition = styled.div`
Expand Down
Loading

1 comment on commit 3ef84b8

@vercel
Copy link

@vercel vercel bot commented on 3ef84b8 Oct 12, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.