diff --git a/package.json b/package.json index 93d9e04..ebd9f78 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "@types/react-beautiful-dnd": "^13.0.0", "@types/react-bootstrap": "^0.32.25", "@types/react-dom": "^17.0.0", + "@types/uuid": "^8.3.0", "bootstrap": "4.6.0", "filesafe-embed": "^1.0.10", "filesafe-js": "^1.0.4", @@ -66,6 +67,7 @@ "sn-stylekit": "2.1.0", "source-map-explorer": "^2.5.1", "typescript": "^4.1.3", + "uuid": "^8.3.2", "web-vitals": "^1.0.1" }, "eslintConfig": { diff --git a/src/components/Balance.tsx b/src/components/Balance.tsx new file mode 100644 index 0000000..5c0d5d2 --- /dev/null +++ b/src/components/Balance.tsx @@ -0,0 +1,94 @@ +import * as React from "react"; +import { Col, Form, Row } from "react-bootstrap"; +export interface BalanceProps { + savingsBalance: number; + updateSavingsBalance: (savingsBalance: number) => void; +} + +export interface BalanceState { + savingsBalance: number; +} + +class Balance extends React.Component { + constructor(props: BalanceProps) { + super(props); + this.state = { + savingsBalance: this.props.savingsBalance + ? this.props.savingsBalance + : 0.0, + }; + this.handleInputChange = this.handleInputChange.bind(this); + this.handleOnBlur = this.handleOnBlur.bind(this); + this.moneyValidation = this.moneyValidation.bind(this); + } + handleInputChange(event: React.ChangeEvent) { + const target = event.target; + const name = target.name; + const value = target.value; + + this.setState({ + savingsBalance: this.moneyValidation(value), + }); + } + handleOnBlur(event: React.FocusEvent): void { + const target = event.target; + const value = target.value; + if (value) { + this.saveBalance(value); + } + } + + saveBalance(balance: string): void { + if (balance) { + this.setState( + { + savingsBalance: this.moneyValidation(balance), + }, + () => + this.props.updateSavingsBalance( + this.moneyValidation(this.state.savingsBalance.toString()) + ) + ); + } + } + //TODO: Do input validation here and return 0 if bad + moneyValidation(value: string): number { + return parseFloat(value) || 0; + } + render() { + return ( +
+ {" "} + + +

~Savings Balance~

+ +
+ + +
+ + ): void => + this.setState({ + savingsBalance: this.moneyValidation(e.target.value), + }) + } + onBlur={this.handleOnBlur} + /> + +
+ +
+
+
+ ); + } +} + +export default Balance; diff --git a/src/components/Editor.tsx b/src/components/Editor.tsx index b7b8dad..a783002 100644 --- a/src/components/Editor.tsx +++ b/src/components/Editor.tsx @@ -1,6 +1,11 @@ +//todo sprinkle comments +//todo code cleanup +import { PlusCircleIcon } from "@primer/octicons-react"; import React from "react"; -import { Container } from "react-bootstrap"; +import { Button, Col, Container, Row } from "react-bootstrap"; import { EditorKit, EditorKitDelegate } from "sn-editor-kit"; +import Balance from "./Balance"; +import GoalItem from "./GoalItem"; import Goals from "./Goals"; export enum HtmlElementId { snComponent = "sn-component", @@ -11,22 +16,37 @@ export enum HtmlClassName { snComponent = "sn-component", textarea = "sk-input contrast textarea", } +export interface Goal { + index: number; + id: string; + itemGoalCost: number; + name: string; +} export interface EditorInterface { printUrl: boolean; text: string; - goals: { id: string; itemGoalCost: number; name: string }[]; + goals: Goal[]; + savingsBalance: number; + addGoal: boolean; + editGoal: boolean; + loaded: boolean; + editGoalID?: string; } - +//todo update this block of code to set the correct initalstate after reading from editorkit const initialState = { printUrl: false, text: "", goals: [ - { id: "1", itemGoalCost: 200, name: "Apple Watch" }, - { id: "2", itemGoalCost: 1200, name: "Macbook" }, - { id: "3", itemGoalCost: 45000, name: "Tesla" }, - { id: "4", itemGoalCost: 65000, name: "Addtion" }, + { index: 1, id: "1", itemGoalCost: 200, name: "Apple Watch" }, + { index: 2, id: "2", itemGoalCost: 1200, name: "Macbook" }, + { index: 0, id: "3", itemGoalCost: 45000, name: "Tesla" }, + { index: 3, id: "4", itemGoalCost: 65000, name: "Addition" }, ], + addGoal: false, + editGoal: false, + savingsBalance: 30.0, + loaded: true, }; let keyMap = new Map(); @@ -39,8 +59,15 @@ export default class Editor extends React.Component<{}, EditorInterface> { this.configureEditorKit(); this.state = initialState; this.updateGoals = this.updateGoals.bind(this); + this.updateSavingsBalance = this.updateSavingsBalance.bind(this); + this.onAddGoal = this.onAddGoal.bind(this); + this.onCancelAddGoal = this.onCancelAddGoal.bind(this); + this.updateIndexes = this.updateIndexes.bind(this); + this.handleSubmitOfGoal = this.handleSubmitOfGoal.bind(this); + this.editGoal = this.editGoal.bind(this); + this.deleteGoal = this.deleteGoal.bind(this); } - + //TODO read goals from editorkit configureEditorKit = () => { let delegate = new EditorKitDelegate({ /** This loads every time a different note is loaded */ @@ -101,12 +128,71 @@ export default class Editor extends React.Component<{}, EditorInterface> { keyMap.delete(e.key); }; - updateGoals(goals: { id: string; itemGoalCost: number; name: string }[]) { + updateGoals( + goals: { index: number; id: string; itemGoalCost: number; name: string }[] + ) { + this.setState( + { + goals, + }, + () => { + this.updateIndexes(); + } + ); + } + updateIndexes() { + let updateGoals = this.state.goals.map((goalItem, index) => { + goalItem.index = index; + return goalItem; + }); + this.setState({ goals: updateGoals }); + } + updateSavingsBalance(savingsBalance: number): void { + this.setState({ + savingsBalance, + }); + } + + onAddGoal() { this.setState({ - goals, + addGoal: true, + editGoal: false, }); } + onCancelAddGoal = () => { + this.setState({ + addGoal: false, + editGoal: false, + // editID: "", + }); + }; + //change me to check out edit mode + handleSubmitOfGoal(goal: Goal): void { + if (this.state.editGoal) { + //Todo write this code to update a goal + } else { + this.setState( + { goals: [...this.state.goals, goal], addGoal: false, editGoal: false }, + () => { + this.updateIndexes(); + } + ); + } + //TODO save goals to editor + } + editGoal(goalID: string) { + this.setState({ + addGoal: false, + editGoal: true, + editGoalID: goalID, + }); + } + deleteGoal(goalID: string) { + //todo write code to delete a goal + alert(goalID); + } + render() { const { text } = this.state; return ( @@ -118,47 +204,55 @@ export default class Editor extends React.Component<{}, EditorInterface> { tabIndex={0} > - - + - {/*

- Edit src/components/Editor.tsx and save to reload. -

-

- Visit the{' '} - - Standard Notes documentation - {' '} - to learn how to work with the Standard Notes API or{' '} - - Learn React - - . -

*/} - - {/* -