From 41e7568cd135fb46fe517c25621a9dd337faa479 Mon Sep 17 00:00:00 2001 From: Zachary Robinson Date: Mon, 13 Nov 2023 19:03:20 -0500 Subject: [PATCH] Add datepicker for editing dates --- package-lock.json | 158 +++++++++++++++++++- package.json | 1 + src/renderer/src/App.tsx | 79 +++++++--- src/renderer/src/components/SlateColumn.tsx | 73 +++++++-- src/renderer/src/util/fakeCardData.ts | 6 +- 5 files changed, 281 insertions(+), 36 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2c7a33b..5e00550 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,6 +25,7 @@ "path-browserify": "^1.0.1", "react-beautiful-dnd": "^13.1.1", "react-contenteditable": "^3.3.7", + "react-date-picker": "^10.5.2", "react-use": "^17.4.0", "uuid": "^9.0.1" }, @@ -1217,6 +1218,19 @@ "@types/node": "*" } }, + "node_modules/@types/lodash": { + "version": "4.14.201", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.201.tgz", + "integrity": "sha512-y9euML0cim1JrykNxADLfaG0FgD1g/yTHwUs/Jg9ZIU7WKj2/4IW9Lbb1WZbvck78W/lfGXFfe+u2EGfIJXdLQ==" + }, + "node_modules/@types/lodash.memoize": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/lodash.memoize/-/lodash.memoize-4.1.9.tgz", + "integrity": "sha512-glY1nQuoqX4Ft8Uk+KfJudOD7DQbbEDF6k9XpGncaohW3RW4eSWBlx6AA0fZCrh40tZcQNH4jS/Oc59J6Eq+aw==", + "dependencies": { + "@types/lodash": "*" + } + }, "node_modules/@types/ms": { "version": "0.7.33", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.33.tgz", @@ -1271,7 +1285,7 @@ }, "node_modules/@types/react-dom": { "version": "18.2.14", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@types/react": "*" @@ -1529,6 +1543,14 @@ "vite": "^4.2.0" } }, + "node_modules/@wojtekmaj/date-utils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@wojtekmaj/date-utils/-/date-utils-1.5.1.tgz", + "integrity": "sha512-+i7+JmNiE/3c9FKxzWFi2IjRJ+KzZl1QPu6QNrsgaa2MuBgXvUy4gA1TVzf/JMdIIloB76xSKikTWuyYAIVLww==", + "funding": { + "url": "https://github.com/wojtekmaj/date-utils?sponsor=1" + } + }, "node_modules/@xmldom/xmldom": { "version": "0.8.10", "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", @@ -2561,6 +2583,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", + "engines": { + "node": ">=6" + } + }, "node_modules/color-convert": { "version": "1.9.3", "dev": true, @@ -2940,6 +2970,14 @@ "node": ">=0.4.0" } }, + "node_modules/detect-element-overflow": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/detect-element-overflow/-/detect-element-overflow-1.4.2.tgz", + "integrity": "sha512-4m6cVOtvm/GJLjo7WFkPfwXoEIIbM7GQwIh4WEa4g7IsNi1YzwUsGL5ApNLrrHL29bHeNeQ+/iZhw+YHqgE2Fw==", + "funding": { + "url": "https://github.com/wojtekmaj/detect-element-overflow?sponsor=1" + } + }, "node_modules/detect-node": { "version": "2.1.0", "license": "MIT", @@ -4417,6 +4455,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-user-locale": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/get-user-locale/-/get-user-locale-2.3.1.tgz", + "integrity": "sha512-VEvcsqKYx7zhZYC1CjecrDC5ziPSpl1gSm0qFFJhHSGDrSC+x4+p1KojWC/83QX//j476gFhkVXP/kNUc9q+bQ==", + "dependencies": { + "@types/lodash.memoize": "^4.1.7", + "lodash.memoize": "^4.1.1" + }, + "funding": { + "url": "https://github.com/wojtekmaj/get-user-locale?sponsor=1" + } + }, "node_modules/glob": { "version": "7.2.3", "dev": true, @@ -5547,6 +5597,11 @@ "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" + }, "node_modules/lodash.merge": { "version": "4.6.2", "dev": true, @@ -5588,6 +5643,14 @@ "node": ">=12" } }, + "node_modules/make-event-props": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/make-event-props/-/make-event-props-1.6.2.tgz", + "integrity": "sha512-iDwf7mA03WPiR8QxvcVHmVWEPfMY1RZXerDVNCRYW7dUr2ppH3J58Rwb39/WG39yTZdRSxr3x+2v22tvI0VEvA==", + "funding": { + "url": "https://github.com/wojtekmaj/make-event-props?sponsor=1" + } + }, "node_modules/matcher": { "version": "3.0.0", "license": "MIT", @@ -6568,6 +6631,31 @@ "react-dom": "^16.8.5 || ^17.0.0 || ^18.0.0" } }, + "node_modules/react-calendar": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/react-calendar/-/react-calendar-4.6.1.tgz", + "integrity": "sha512-MvCPdvxEvq7wICBhFxlYwxS2+IsVvSjTcmlr0Kl3yDRVhoX7btNg0ySJx5hy9rb1eaM4nDpzQcW5c87nfQ8n8w==", + "dependencies": { + "@wojtekmaj/date-utils": "^1.1.3", + "clsx": "^2.0.0", + "get-user-locale": "^2.2.1", + "prop-types": "^15.6.0", + "tiny-warning": "^1.0.0" + }, + "funding": { + "url": "https://github.com/wojtekmaj/react-calendar?sponsor=1" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/react-contenteditable": { "version": "3.3.7", "resolved": "https://registry.npmjs.org/react-contenteditable/-/react-contenteditable-3.3.7.tgz", @@ -6580,6 +6668,34 @@ "react": ">=16.3" } }, + "node_modules/react-date-picker": { + "version": "10.5.2", + "resolved": "https://registry.npmjs.org/react-date-picker/-/react-date-picker-10.5.2.tgz", + "integrity": "sha512-EwLNYPy+/2p7VwsAWnitPhtkC2tesABkZNlAAIEPZeHucyMlO5KB6z55POdtamu6T6vs0RY2G5EVgxDaxlj0MQ==", + "dependencies": { + "@wojtekmaj/date-utils": "^1.1.3", + "clsx": "^2.0.0", + "get-user-locale": "^2.2.1", + "make-event-props": "^1.6.0", + "prop-types": "^15.6.0", + "react-calendar": "^4.6.0", + "react-fit": "^1.7.0", + "update-input-width": "^1.4.0" + }, + "funding": { + "url": "https://github.com/wojtekmaj/react-date-picker?sponsor=1" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/react-dom": { "version": "18.2.0", "license": "MIT", @@ -6591,6 +6707,33 @@ "react": "^18.2.0" } }, + "node_modules/react-fit": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/react-fit/-/react-fit-1.7.1.tgz", + "integrity": "sha512-y/TYovCCBzfIwRJsbLj0rH4Es40wPQhU5GPPq9GlbdF09b0OdzTdMSkBza0QixSlgFzTm6dkM7oTFzaVvaBx+w==", + "dependencies": { + "detect-element-overflow": "^1.4.0", + "prop-types": "^15.6.0", + "tiny-warning": "^1.0.0" + }, + "funding": { + "url": "https://github.com/wojtekmaj/react-fit?sponsor=1" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "@types/react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -7780,6 +7923,11 @@ "resolved": "https://registry.npmjs.org/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz", "integrity": "sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==" }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, "node_modules/titleize": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz", @@ -8036,6 +8184,14 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/update-input-width": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/update-input-width/-/update-input-width-1.4.2.tgz", + "integrity": "sha512-/p0XLhrQQQ4bMWD7bL9duYObwYCO1qGr8R19xcMmoMSmXuQ7/1//veUnCObQ7/iW6E2pGS6rFkS4TfH4ur7e/g==", + "funding": { + "url": "https://github.com/wojtekmaj/update-input-width?sponsor=1" + } + }, "node_modules/uri-js": { "version": "4.4.1", "license": "BSD-2-Clause", diff --git a/package.json b/package.json index 7e389ee..f5bf8fe 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "path-browserify": "^1.0.1", "react-beautiful-dnd": "^13.1.1", "react-contenteditable": "^3.3.7", + "react-date-picker": "^10.5.2", "react-use": "^17.4.0", "uuid": "^9.0.1" }, diff --git a/src/renderer/src/App.tsx b/src/renderer/src/App.tsx index 5561d31..a5d3528 100644 --- a/src/renderer/src/App.tsx +++ b/src/renderer/src/App.tsx @@ -101,7 +101,7 @@ function App(): JSX.Element { { type: "day", id: uuidv4(), - day: "sept 19", + day: "sept 19 2023", }, { type: "file", @@ -148,12 +148,14 @@ function App(): JSX.Element { > New Column - {showDev && } + {showDev && ( + + )} @@ -229,23 +231,54 @@ function App(): JSX.Element { return { ...col, - cards: col.cards.map((card) => { - if (card.id !== id) { - return card; - } + cards: col.cards.reduce( + (filtered, card) => { + if (card.id !== id) { + filtered.push(card); + return filtered; + } - if (card.type === "day") { - return { - ...card, - day: newName, - }; - } else { - return { - ...card, - fileName: newName, - }; - } - }), + if (newName == "") { + return filtered; + } + + if (card.type === "day") { + filtered.push({ + ...card, + day: newName, + }); + } else { + filtered.push({ + ...card, + fileName: newName, + }); + } + return filtered; + }, + [] as (SlateFile | SlateDayHeader)[] + ), + }; + }), + })) + } + addNewDate={() => + setData((old) => ({ + ...old, + columns: old.columns.map((col) => { + if (col.id !== colData.id) { + return col; + } + + return { + ...col, + cards: [ + ...col.cards, + { + type: "day", + id: uuidv4(), + day: new Date().toString(), + }, + ], }; }), })) diff --git a/src/renderer/src/components/SlateColumn.tsx b/src/renderer/src/components/SlateColumn.tsx index b226927..3c1e870 100644 --- a/src/renderer/src/components/SlateColumn.tsx +++ b/src/renderer/src/components/SlateColumn.tsx @@ -1,20 +1,25 @@ import { Draggable, Droppable } from "react-beautiful-dnd"; -import { createRef, useState } from "react"; +import { RefObject, createRef, useRef, useState } from "react"; import { useElectronStore } from "../util/useElectronStore"; import SlateCard from "./SlateCard"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faSquareMinus } from "@fortawesome/free-regular-svg-icons"; import { faSquarePlus } from "@fortawesome/free-regular-svg-icons"; import { faTrashCan } from "@fortawesome/free-regular-svg-icons"; +import DatePicker from "react-date-picker"; import ContentEditable from "react-contenteditable"; +import "react-date-picker/dist/DatePicker.css"; +import "react-calendar/dist/Calendar.css"; export default function SlateColumn( props: SlateColumn & { onNameChange: (newName: string) => void; onInnerNameChange: (id: string, newName: string) => void; + addNewDate: () => void; } ) { - const { name, id, cards, onNameChange, onInnerNameChange } = props; + const { name, id, cards, onNameChange, onInnerNameChange, addNewDate } = + props; const [collapsed, setCollapsed] = useState(false); const [data, setData] = useElectronStore("cards"); @@ -33,13 +38,14 @@ export default function SlateColumn( setData(dataCopy); } }; - const editableRef = createRef(); + const titleEditRef = createRef(); + let lastRef: RefObject; return (
onNameChange(e.target.value)} tagName="h1" @@ -76,7 +82,7 @@ export default function SlateColumn( {(provided, snapshot) => (
<> - {cards.map((item) => { + {cards.map((item, index) => { if (item.type == "day") { return ( {(provided, snapshot) => { - const innerEditRef = createRef() + const [dateEdit, setDateEdit] = useState(false); + return (
- + /> */} + {dateEdit ? ( + { + setDateEdit(false); + onInnerNameChange( + item.id, + newval?.toString() || "" + ); + }} + onCalendarClose={() => setDateEdit(false)} + value={item.day} + isOpen={true} + /> + ) : ( +

setDateEdit(true)} + > + {new Date(item.day).toLocaleString( + "en-US", + { + day: "2-digit", + month: "short", + } + )} +

+ )} +
); @@ -110,7 +146,12 @@ export default function SlateColumn( ); } else { return ( - + ); } })} @@ -119,6 +160,20 @@ export default function SlateColumn(
)} +
{ + addNewDate(); + requestAnimationFrame(() => { + console.log(lastRef); + }); + }} + > +

+ Add date... +

+
+
)}
diff --git a/src/renderer/src/util/fakeCardData.ts b/src/renderer/src/util/fakeCardData.ts index a78b05d..64491ec 100644 --- a/src/renderer/src/util/fakeCardData.ts +++ b/src/renderer/src/util/fakeCardData.ts @@ -8,7 +8,7 @@ export default function fakeCardData(): FileDatabase { { type: "day", id: "a-day-sept19", - day: "sept 19", + day: "sept 19 2023", }, { type: "file", @@ -29,7 +29,7 @@ export default function fakeCardData(): FileDatabase { { type: "day", id: "a-day-sept20", - day: "sept 20", + day: "sept 20 2023", }, { type: "file", @@ -48,7 +48,7 @@ export default function fakeCardData(): FileDatabase { { type: "day", id: "b-day-sept19", - day: "sept 19", + day: "sept 19 2023", }, { type: "file",