From aa820d4910d3108cb5c543429d5f77d14b501bd7 Mon Sep 17 00:00:00 2001 From: Michael Zhang Date: Wed, 23 Aug 2023 21:47:25 -0500 Subject: [PATCH] toggle switches --- lib/queries.ts | 35 +++++ package-lock.json | 203 ++++++++++++++++++++++++++- package.json | 3 +- randomshit.txt | 22 +++ src/App.module.scss | 4 + src/App.tsx | 23 +-- src/calendar/Calendar.module.scss | 7 + src/calendar/Calendar.tsx | 42 ++++-- src/calendar/Month.tsx | 54 +++---- src/global.scss | 9 ++ src/widgets/ToggleSwitch.module.scss | 19 +++ src/widgets/ToggleSwitch.tsx | 33 +++++ 12 files changed, 396 insertions(+), 58 deletions(-) create mode 100644 lib/queries.ts create mode 100644 randomshit.txt create mode 100644 src/widgets/ToggleSwitch.module.scss create mode 100644 src/widgets/ToggleSwitch.tsx diff --git a/lib/queries.ts b/lib/queries.ts new file mode 100644 index 0000000..c58bba9 --- /dev/null +++ b/lib/queries.ts @@ -0,0 +1,35 @@ +import { format } from "date-fns"; +import { useQuery } from "react-query"; + +type JournalQueryDate = JournalEntry[]; + +interface JournalEntry { + "journal-day": number; + "original-name": string; +} + +export function useJournals(dateStart: Date, dateEnd: Date) { + const fmtStart = journalFmt(dateStart); + const fmtEnd = journalFmt(dateEnd); + + return useQuery(["journals", dateStart, dateEnd], async () => { + const journals: JournalQueryDate[] = await logseq.DB.datascriptQuery(` + [:find (pull ?p [*]) + :where + [?b :block/page ?p] + [?p :block/journal? true] + [?p :block/journal-day ?d] + [(>= ?d ${fmtStart})] [(<= ?d ${fmtEnd})]] + `); + + return new Map( + journals + .flatMap((dates) => dates) + .map((entry) => [entry["journal-day"].toString(), entry]) + ); + }); +} + +export function journalFmt(date: Date) { + return format(date, "YMMdd"); +} diff --git a/package-lock.json b/package-lock.json index 59d3001..8ecd4b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,8 @@ "date-fns": "^2.30.0", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-keybind": "^0.9.4" + "react-keybind": "^0.9.4", + "react-query": "^3.39.3" }, "devDependencies": { "@logseq/libs": "^0.0.1-alpha.29", @@ -868,6 +869,19 @@ "node": ">= 8" } }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/big-integer": { + "version": "1.6.51", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", + "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", + "engines": { + "node": ">=0.6" + } + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -877,6 +891,15 @@ "node": ">=8" } }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", @@ -889,6 +912,21 @@ "node": ">=8" } }, + "node_modules/broadcast-channel": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/broadcast-channel/-/broadcast-channel-3.7.0.tgz", + "integrity": "sha512-cIAKJXAxGJceNZGTZSBzMxzyOn72cVgPnKx4dc6LRjQgbaJUQqhy5rzL3zbMxkMWsGKkv2hSFkPRMEXfoMZ2Mg==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "detect-node": "^2.1.0", + "js-sha3": "0.8.0", + "microseconds": "0.2.0", + "nano-time": "1.0.0", + "oblivious-set": "1.0.0", + "rimraf": "3.0.2", + "unload": "2.2.0" + } + }, "node_modules/browserslist": { "version": "4.21.10", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", @@ -1002,6 +1040,11 @@ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, "node_modules/convert-source-map": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", @@ -1046,6 +1089,11 @@ } } }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" + }, "node_modules/dompurify": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.1.tgz", @@ -1147,6 +1195,11 @@ "node": ">=8" } }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -1170,6 +1223,25 @@ "node": ">=6.9.0" } }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", @@ -1212,11 +1284,19 @@ "integrity": "sha512-808ZFYMsIRAjLAu5xkKo0TsbY9LBy9H5MazTKIEHerNkg0ymgilGfBPMR/3G7d/ihGmuK2Hw8S1izY2d3kd3wA==", "dev": true }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, "node_modules/inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "dev": true + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" }, "node_modules/is-binary-path": { "version": "2.1.0", @@ -1260,6 +1340,11 @@ "node": ">=0.12.0" } }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -1324,12 +1409,45 @@ "yallist": "^3.0.2" } }, + "node_modules/match-sorter": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.1.tgz", + "integrity": "sha512-mxybbo3pPNuA+ZuCUhm5bwNkXrJTbsk5VWbR5wiwz/GC6LIiegBGn2w3O08UG/jdbYLinw51fSQ5xNU1U3MgBw==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "remove-accents": "0.4.2" + } + }, + "node_modules/microseconds": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/microseconds/-/microseconds-0.2.0.tgz", + "integrity": "sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA==" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "node_modules/nano-time": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/nano-time/-/nano-time-1.0.0.tgz", + "integrity": "sha512-flnngywOoQ0lLQOTRNexn2gGSNuM9bKj9RZAWSzhQ+UJYaAFG9bac4DW9VHjUAzrOaIcajHybCTHe/bkvozQqA==", + "dependencies": { + "big-integer": "^1.6.16" + } + }, "node_modules/nanoid": { "version": "3.3.6", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", @@ -1373,6 +1491,19 @@ "node": ">=0.10.0" } }, + "node_modules/oblivious-set": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/oblivious-set/-/oblivious-set-1.0.0.tgz", + "integrity": "sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw==" + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, "node_modules/path": { "version": "0.12.7", "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", @@ -1383,6 +1514,14 @@ "util": "^0.10.3" } }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -1466,6 +1605,31 @@ "resolved": "https://registry.npmjs.org/react-keybind/-/react-keybind-0.9.4.tgz", "integrity": "sha512-JVlXJ4ONQFQtEDZqXpc5NZ3oLEJtj7lKCPMLsbAO6FfkXJ21VHKyDtiLUIMio3d3oSC8QfxDOQtUEeVrMW6HfQ==" }, + "node_modules/react-query": { + "version": "3.39.3", + "resolved": "https://registry.npmjs.org/react-query/-/react-query-3.39.3.tgz", + "integrity": "sha512-nLfLz7GiohKTJDuT4us4X3h/8unOh+00MLb2yJoGTPjxKs2bc1iDhkNx2bd5MKklXnOD3NrVZ+J2UXujA5In4g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "broadcast-channel": "^3.4.1", + "match-sorter": "^6.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, "node_modules/react-refresh": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz", @@ -1492,6 +1656,25 @@ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" }, + "node_modules/remove-accents": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz", + "integrity": "sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA==" + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/rollup": { "version": "3.28.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.28.1.tgz", @@ -1633,6 +1816,15 @@ "node": ">=14.17" } }, + "node_modules/unload": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unload/-/unload-2.2.0.tgz", + "integrity": "sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA==", + "dependencies": { + "@babel/runtime": "^7.6.2", + "detect-node": "^2.0.4" + } + }, "node_modules/update-browserslist-db": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", @@ -1746,6 +1938,11 @@ } } }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", diff --git a/package.json b/package.json index ef8b89a..121a29c 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "date-fns": "^2.30.0", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-keybind": "^0.9.4" + "react-keybind": "^0.9.4", + "react-query": "^3.39.3" } } diff --git a/randomshit.txt b/randomshit.txt new file mode 100644 index 0000000..793b067 --- /dev/null +++ b/randomshit.txt @@ -0,0 +1,22 @@ +const monthColors = [ + "#AA3939", + "#FFAAAA", + "#D46A6A", + "#801515", + "#550000", + "#AA6C39", + "#FFD1AA", + "#D49A6A", + "#804515", + "#552700", + "#226666", + "#669999", + "#407F7F", + "#0D4D4D", + "#003333", + "#2D882D", + "#88CC88", + "#55AA55", + "#116611", + "#004400", +]; diff --git a/src/App.module.scss b/src/App.module.scss index 3844aec..9cb9be8 100644 --- a/src/App.module.scss +++ b/src/App.module.scss @@ -9,4 +9,8 @@ main.app { .header { padding-top: 40px; + flex-basis: 120px; + + display: flex; + align-items: center; } diff --git a/src/App.tsx b/src/App.tsx index f2040aa..302fa97 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,6 +2,9 @@ import { endOfMonth, format, startOfMonth } from "date-fns"; import styles from "./App.module.scss"; import Calendar from "./calendar/Calendar"; import KeyboardShortcutWrapper from "./KeyboardShortcutWrapper"; +import { QueryClient, QueryClientProvider } from "react-query"; + +const queryClient = new QueryClient(); export default function App() { const onDateClick = async (date: Date) => { @@ -44,15 +47,17 @@ export default function App() { const exit = () => logseq.hideMainUI(); return ( - -
-
- Header - -
+ + +
+
+ Header + +
- -
-
+ +
+
+ ); } diff --git a/src/calendar/Calendar.module.scss b/src/calendar/Calendar.module.scss index 57cddcf..d7f9c89 100644 --- a/src/calendar/Calendar.module.scss +++ b/src/calendar/Calendar.module.scss @@ -13,6 +13,13 @@ .title { font-size: 22px; + display: flex; + justify-content: space-between; + } + + .controlButtons { + display: flex; + gap: 12px; } } diff --git a/src/calendar/Calendar.tsx b/src/calendar/Calendar.tsx index cf398f4..12582f1 100644 --- a/src/calendar/Calendar.tsx +++ b/src/calendar/Calendar.tsx @@ -9,6 +9,8 @@ import { } from "date-fns"; import Month from "./Month"; import { monthNameOf, weekBoundsOfMonth } from "lib/month"; +import { useJournals } from "lib/queries"; +import ToggleSwitch from "src/widgets/ToggleSwitch"; const daysOfWeek = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; const NUM_MONTHS_SHOWN = 5; @@ -32,6 +34,9 @@ export default function Calendar({ onDateClick }: CalendarProps) { range.map((x) => addMonths(centerMonth, x)) ); + const startDate = monthsShown[0]; + const endDate = monthsShown[NUM_MONTHS_SHOWN - 1]; + const [firstLoad, setFirstLoad] = useState(true); useEffect(() => { if (firstLoad && scrollyEl && viewportHeight > 0) { @@ -72,7 +77,7 @@ export default function Calendar({ onDateClick }: CalendarProps) { useEffect(() => { if (!scrollyEl) return; - const children = [...scrollyEl.children]; + const children: HTMLElement[] = [...scrollyEl.children]; if (children.length !== NUM_MONTHS_SHOWN) throw new Error("wtf"); const firstChild = children[0]; const lastChild = children[NUM_MONTHS_SHOWN - 1]; @@ -86,7 +91,7 @@ export default function Calendar({ onDateClick }: CalendarProps) { if (entry.target === firstChild) { console.log("intersected"); - const firstChildDate = new Date(firstChild.dataset.isodate); + const firstChildDate = new Date(firstChild.dataset.isodate!); const prevMonth = subMonths(firstChildDate, 1); newMonthsShown = [prevMonth, ...monthsShown]; newMonthsShown = newMonthsShown.slice(0, NUM_MONTHS_SHOWN); @@ -96,7 +101,7 @@ export default function Calendar({ onDateClick }: CalendarProps) { scrollyEl.scrollTop - firstChild.offsetTop, ]); } else if (entry.target === lastChild) { - const lastChildDate = new Date(lastChild.dataset.isodate); + const lastChildDate = new Date(lastChild.dataset.isodate!); const nextMonth = addMonths(lastChildDate, 1); newMonthsShown = [...monthsShown, nextMonth]; newMonthsShown = newMonthsShown.slice(-NUM_MONTHS_SHOWN); @@ -139,19 +144,31 @@ export default function Calendar({ onDateClick }: CalendarProps) { // middleMonthEl?.scrollIntoView(); // }, [middleMonthRef]); + const [currentLayout, setCurrentLayout] = useState("Month"); + const [currentView, setCurrentView] = useState("Calendar"); + return (
- {monthName} - {centerMonth.getFullYear()} - (months shown:{" "} - {JSON.stringify( - monthsShown.map((x) => - x.toLocaleDateString("default", { month: "long" }) - ) - )} - ) +
+ {monthName} + {centerMonth.getFullYear()} +
+ +
+ + + +
@@ -173,6 +190,7 @@ export default function Calendar({ onDateClick }: CalendarProps) { const props = { month, dateGridHeight, + dateCellHeight, }; const ref = undefined; // (month === currentlyShownMonth && middleMonthRef) || undefined; diff --git a/src/calendar/Month.tsx b/src/calendar/Month.tsx index feb9503..d397384 100644 --- a/src/calendar/Month.tsx +++ b/src/calendar/Month.tsx @@ -11,40 +11,26 @@ import { } from "date-fns"; import classNames from "classnames"; import { weekBoundsOfMonth } from "lib/month"; +import { journalFmt, useJournals } from "lib/queries"; interface MonthProps { month: Date; dateGridHeight: number; + dateCellHeight: number; onDateClick?: (_: Date) => void; } -const monthColors = [ - "#AA3939", - "#FFAAAA", - "#D46A6A", - "#801515", - "#550000", - "#AA6C39", - "#FFD1AA", - "#D49A6A", - "#804515", - "#552700", - "#226666", - "#669999", - "#407F7F", - "#0D4D4D", - "#003333", - "#2D882D", - "#88CC88", - "#55AA55", - "#116611", - "#004400", -]; - -function Month({ month, dateGridHeight, onDateClick }: MonthProps, ref) { +function Month( + { month, dateGridHeight, dateCellHeight, onDateClick }: MonthProps, + ref +) { const now = new Date(); const monthName = month.toLocaleString("default", { month: "long" }); + const firstDay = startOfMonth(month); + const lastDay = endOfMonth(month); + const { status, data: journals } = useJournals(firstDay, lastDay); + const [startWeek, endWeek] = weekBoundsOfMonth(month); const numWeeks = differenceInWeeks(endWeek, startWeek) + 1; const weeksArr = Array(numWeeks) @@ -61,13 +47,18 @@ function Month({ month, dateGridHeight, onDateClick }: MonthProps, ref) { <>
{datesArr.map((date) => { const isFirst = isSameDay(date, startOfMonth(date)); const isToday = isSameDay(date, now); + + const journalDate = journalFmt(date); + const hasJournal = journals?.has(journalDate); + return (
onDateClick?.(date)} > - + {isFirst && monthName} {date.getDate()}
+ +
+

j: {JSON.stringify(hasJournal)}

+
); })} diff --git a/src/global.scss b/src/global.scss index 6fb40cd..b0c2e1e 100644 --- a/src/global.scss +++ b/src/global.scss @@ -1,3 +1,11 @@ +:root { + --text-color: black; + + @media (prefers-color-scheme: dark) { + --text-color: white; + } +} + html, body, #app { @@ -8,4 +16,5 @@ body, padding: 0; font-family: sans-serif; + color: var(--text-color); } diff --git a/src/widgets/ToggleSwitch.module.scss b/src/widgets/ToggleSwitch.module.scss new file mode 100644 index 0000000..0e3c2ff --- /dev/null +++ b/src/widgets/ToggleSwitch.module.scss @@ -0,0 +1,19 @@ +.toggleSwitch { + display: flex; + gap: 6px; + + border-radius: 9999px; + background-color: lightgray; + font-size: 14px; + padding: 4px; +} + +.option { + border-radius: 9999px; + padding: 4px 12px; + cursor: pointer; + + &.selected { + background-color: gray; + } +} diff --git a/src/widgets/ToggleSwitch.tsx b/src/widgets/ToggleSwitch.tsx new file mode 100644 index 0000000..66c0211 --- /dev/null +++ b/src/widgets/ToggleSwitch.tsx @@ -0,0 +1,33 @@ +import classNames from "classnames"; +import styles from "./ToggleSwitch.module.scss"; + +interface ToggleSwitchProps { + options: string[]; + defaultOption?: string; + value: string; + setValue: (_: string) => any; +} + +export default function ToggleSwitch({ + options, + defaultOption, + value, + setValue, +}: ToggleSwitchProps) { + return ( +
+ {options.map((option) => { + const isSelected = option === value; + return ( +
setValue(option)} + > + {option} +
+ ); + })} +
+ ); +}