├── .github ├── FUNDING.yml └── workflows │ └── publish.yml ├── .gitignore ├── .postcssrc ├── LICENSE.md ├── README.md ├── icon.svg ├── package-lock.json ├── package.json ├── screenshots ├── demo.gif └── demo2.gif ├── src ├── App.css ├── RecurCard.tsx ├── Recurrence.tsx ├── handleClosePopup.ts ├── index.html ├── index.tsx └── tailwind.css └── tailwind.config.js /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [hkgnp] 2 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Build plugin 2 | 3 | on: 4 | push: 5 | # Sequence of patterns matched against refs/tags 6 | tags: 7 | - '*' # Push events to matching any tag format, i.e. 1.0, 20.15.10 8 | 9 | env: 10 | PLUGIN_NAME: ${{ github.event.repository.name }} 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v2 18 | - name: Use Node.js 19 | uses: actions/setup-node@v1 20 | with: 21 | node-version: '16.x' # You might need to adjust this value to your own version 22 | - name: Build 23 | id: build 24 | run: | 25 | npm i && npm run build 26 | mkdir ${{ env.PLUGIN_NAME }} 27 | cp README.md package.json icon.svg ${{ env.PLUGIN_NAME }} 28 | mv dist ${{ env.PLUGIN_NAME }} 29 | zip -r ${{ env.PLUGIN_NAME }}.zip ${{ env.PLUGIN_NAME }} 30 | ls 31 | echo "::set-output name=tag_name::$(git tag --sort version:refname | tail -n 1)" 32 | - name: Create Release 33 | uses: ncipollo/release-action@v1 34 | id: create_release 35 | env: 36 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 37 | VERSION: ${{ github.ref }} 38 | with: 39 | allowUpdates: true 40 | draft: false 41 | prerelease: false 42 | 43 | - name: Upload zip file 44 | id: upload_zip 45 | uses: actions/upload-release-asset@v1 46 | env: 47 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 48 | with: 49 | upload_url: ${{ steps.create_release.outputs.upload_url }} 50 | asset_path: ./${{ env.PLUGIN_NAME }}.zip 51 | asset_name: ${{ env.PLUGIN_NAME }}-${{ steps.build.outputs.tag_name }}.zip 52 | asset_content_type: application/zip 53 | 54 | - name: Upload package.json 55 | id: upload_metadata 56 | uses: actions/upload-release-asset@v1 57 | env: 58 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 59 | with: 60 | upload_url: ${{ steps.create_release.outputs.upload_url }} 61 | asset_path: ./package.json 62 | asset_name: package.json 63 | asset_content_type: application/json 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | # Logs 3 | logs 4 | *.log 5 | npm-debug.log* 6 | yarn-debug.log* 7 | yarn-error.log* 8 | lerna-debug.log* 9 | .pnpm-debug.log* 10 | 11 | # Diagnostic reports (https://nodejs.org/api/report.html) 12 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 13 | 14 | # Runtime data 15 | pids 16 | *.pid 17 | *.seed 18 | *.pid.lock 19 | 20 | # Directory for instrumented libs generated by jscoverage/JSCover 21 | lib-cov 22 | 23 | # Coverage directory used by tools like istanbul 24 | coverage 25 | *.lcov 26 | 27 | # nyc test coverage 28 | .nyc_output 29 | 30 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 31 | .grunt 32 | 33 | # Bower dependency directory (https://bower.io/) 34 | bower_components 35 | 36 | # node-waf configuration 37 | .lock-wscript 38 | 39 | # Compiled binary addons (https://nodejs.org/api/addons.html) 40 | build/Release 41 | 42 | # Dependency directories 43 | node_modules/ 44 | jspm_packages/ 45 | 46 | # Snowpack dependency directory (https://snowpack.dev/) 47 | web_modules/ 48 | 49 | # TypeScript cache 50 | *.tsbuildinfo 51 | 52 | # Optional npm cache directory 53 | .npm 54 | 55 | # Optional eslint cache 56 | .eslintcache 57 | 58 | # Microbundle cache 59 | .rpt2_cache/ 60 | .rts2_cache_cjs/ 61 | .rts2_cache_es/ 62 | .rts2_cache_umd/ 63 | 64 | # Optional REPL history 65 | .node_repl_history 66 | 67 | # Output of 'npm pack' 68 | *.tgz 69 | 70 | # Yarn Integrity file 71 | .yarn-integrity 72 | 73 | # dotenv environment variables file 74 | .env 75 | .env.test 76 | .env.production 77 | 78 | # parcel-bundler cache (https://parceljs.org/) 79 | .cache 80 | .parcel-cache 81 | 82 | # Next.js build output 83 | .next 84 | out 85 | 86 | # Nuxt.js build / generate output 87 | .nuxt 88 | dist 89 | 90 | # Gatsby files 91 | .cache/ 92 | # Comment in the public line in if your project uses Gatsby and not Next.js 93 | # https://nextjs.org/blog/next-9-1#public-directory-support 94 | # public 95 | 96 | # vuepress build output 97 | .vuepress/dist 98 | 99 | # Serverless directories 100 | .serverless/ 101 | 102 | # FuseBox cache 103 | .fusebox/ 104 | 105 | # DynamoDB Local files 106 | .dynamodb/ 107 | 108 | # TernJS port file 109 | .tern-port 110 | 111 | # Stores VSCode versions used for testing VSCode extensions 112 | .vscode-test 113 | 114 | # yarn v2 115 | .yarn/cache 116 | .yarn/unplugged 117 | .yarn/build-state.yml 118 | .yarn/install-state.gz 119 | .pnp.* -------------------------------------------------------------------------------- /.postcssrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": { 3 | "postcss-import": {}, 4 | "tailwindcss/nesting": {}, 5 | "tailwindcss": {}, 6 | "autoprefixer": {} 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 hkgnp 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [[:gift_heart: Sponsor this project on Github](https://github.com/sponsors/hkgnp) or [:coffee: Get me a coffee](https://www.buymeacoffee.com/hkgnp.dev) if you like this plugin! 2 | 3 | # Overview 4 | 5 | This plugin allows you to quickly add recurring blocks based on your desired recurrence. It also allows you to delete inserted recurring blocks as well! 6 | 7 | When used with the [logseq-trackhabits2-plugin](https://github.com/hkgnp/logseq-trackhabits2-plugin), you can easily create habits to track! 8 | 9 |  10 | 11 |  12 | 13 | # Installation 14 | 15 | If not in the marketplace, [download the release](https://github.com/hkgnp/logseq-recurrence-plugin/releases) and manually load it in Logseq. 16 | 17 | # Usage 18 | 19 | 1. Create the block that you would want to recur. 20 | 2. At the end of the line, type `/Set recurrence`. 21 | 3. Choose the desired recurrence options. 22 | 4. Click `Create Blocks` and you are done! 23 | 24 | # Credits 25 | 26 | - [DayJS](https://day.js.org/) 27 | -------------------------------------------------------------------------------- /icon.svg: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "logseq": { 3 | "id": "logseq-recurrence-plugin", 4 | "title": "logseq-recurrence-plugin", 5 | "icon": "./icon.svg" 6 | }, 7 | "name": "logseq-recurrence-plugin", 8 | "version": "1.0.7", 9 | "description": "", 10 | "main": "dist/index.html", 11 | "targets": { 12 | "main": false 13 | }, 14 | "scripts": { 15 | "test": "echo \"Error: no test specified\" && exit 1", 16 | "build": "postcss src/tailwind.css -o src/App.css && parcel build --no-source-maps src/index.html --public-url ./" 17 | }, 18 | "keywords": [], 19 | "author": "hkgnp", 20 | "license": "MIT", 21 | "dependencies": { 22 | "@logseq/libs": "^0.0.1-alpha.34", 23 | "autoprefix": "^1.0.1", 24 | "dayjs": "^1.10.7", 25 | "logseq-dateutils": "^0.0.12", 26 | "postcss-cli": "^9.1.0", 27 | "postcss-import": "^14.0.2", 28 | "react": "^17.0.2", 29 | "react-datepicker": "^4.6.0", 30 | "react-dom": "^17.0.2", 31 | "tailwindcss": "^3.0.15" 32 | }, 33 | "devDependencies": { 34 | "@types/react": "^17.0.38", 35 | "@types/react-datepicker": "^4.4.0", 36 | "@types/react-dom": "^17.0.11", 37 | "parcel": "^2.2.0" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /screenshots/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benjypng/logseq-recurrence-plugin/e4d8ea01cc3f55cf48faa659b899304cd2575d7a/screenshots/demo.gif -------------------------------------------------------------------------------- /screenshots/demo2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benjypng/logseq-recurrence-plugin/e4d8ea01cc3f55cf48faa659b899304cd2575d7a/screenshots/demo2.gif -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | /* 2 | ! tailwindcss v3.0.19 | MIT License | https://tailwindcss.com 3 | *//* 4 | 1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) 5 | 2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) 6 | */ 7 | 8 | *, 9 | ::before, 10 | ::after { 11 | box-sizing: border-box; /* 1 */ 12 | border-width: 0; /* 2 */ 13 | border-style: solid; /* 2 */ 14 | border-color: #e5e7eb; /* 2 */ 15 | } 16 | 17 | ::before, 18 | ::after { 19 | --tw-content: ''; 20 | } 21 | 22 | /* 23 | 1. Use a consistent sensible line-height in all browsers. 24 | 2. Prevent adjustments of font size after orientation changes in iOS. 25 | 3. Use a more readable tab size. 26 | 4. Use the user's configured `sans` font-family by default. 27 | */ 28 | 29 | html { 30 | line-height: 1.5; /* 1 */ 31 | -webkit-text-size-adjust: 100%; /* 2 */ 32 | -moz-tab-size: 4; /* 3 */ 33 | -o-tab-size: 4; 34 | tab-size: 4; /* 3 */ 35 | font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; /* 4 */ 36 | } 37 | 38 | /* 39 | 1. Remove the margin in all browsers. 40 | 2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. 41 | */ 42 | 43 | body { 44 | margin: 0; /* 1 */ 45 | line-height: inherit; /* 2 */ 46 | } 47 | 48 | /* 49 | 1. Add the correct height in Firefox. 50 | 2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) 51 | 3. Ensure horizontal rules are visible by default. 52 | */ 53 | 54 | hr { 55 | height: 0; /* 1 */ 56 | color: inherit; /* 2 */ 57 | border-top-width: 1px; /* 3 */ 58 | } 59 | 60 | /* 61 | Add the correct text decoration in Chrome, Edge, and Safari. 62 | */ 63 | 64 | abbr:where([title]) { 65 | -webkit-text-decoration: underline dotted; 66 | text-decoration: underline dotted; 67 | } 68 | 69 | /* 70 | Remove the default font size and weight for headings. 71 | */ 72 | 73 | h1, 74 | h2, 75 | h3, 76 | h4, 77 | h5, 78 | h6 { 79 | font-size: inherit; 80 | font-weight: inherit; 81 | } 82 | 83 | /* 84 | Reset links to optimize for opt-in styling instead of opt-out. 85 | */ 86 | 87 | a { 88 | color: inherit; 89 | text-decoration: inherit; 90 | } 91 | 92 | /* 93 | Add the correct font weight in Edge and Safari. 94 | */ 95 | 96 | b, 97 | strong { 98 | font-weight: bolder; 99 | } 100 | 101 | /* 102 | 1. Use the user's configured `mono` font family by default. 103 | 2. Correct the odd `em` font sizing in all browsers. 104 | */ 105 | 106 | code, 107 | kbd, 108 | samp, 109 | pre { 110 | font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; /* 1 */ 111 | font-size: 1em; /* 2 */ 112 | } 113 | 114 | /* 115 | Add the correct font size in all browsers. 116 | */ 117 | 118 | small { 119 | font-size: 80%; 120 | } 121 | 122 | /* 123 | Prevent `sub` and `sup` elements from affecting the line height in all browsers. 124 | */ 125 | 126 | sub, 127 | sup { 128 | font-size: 75%; 129 | line-height: 0; 130 | position: relative; 131 | vertical-align: baseline; 132 | } 133 | 134 | sub { 135 | bottom: -0.25em; 136 | } 137 | 138 | sup { 139 | top: -0.5em; 140 | } 141 | 142 | /* 143 | 1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) 144 | 2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) 145 | 3. Remove gaps between table borders by default. 146 | */ 147 | 148 | table { 149 | text-indent: 0; /* 1 */ 150 | border-color: inherit; /* 2 */ 151 | border-collapse: collapse; /* 3 */ 152 | } 153 | 154 | /* 155 | 1. Change the font styles in all browsers. 156 | 2. Remove the margin in Firefox and Safari. 157 | 3. Remove default padding in all browsers. 158 | */ 159 | 160 | button, 161 | input, 162 | optgroup, 163 | select, 164 | textarea { 165 | font-family: inherit; /* 1 */ 166 | font-size: 100%; /* 1 */ 167 | line-height: inherit; /* 1 */ 168 | color: inherit; /* 1 */ 169 | margin: 0; /* 2 */ 170 | padding: 0; /* 3 */ 171 | } 172 | 173 | /* 174 | Remove the inheritance of text transform in Edge and Firefox. 175 | */ 176 | 177 | button, 178 | select { 179 | text-transform: none; 180 | } 181 | 182 | /* 183 | 1. Correct the inability to style clickable types in iOS and Safari. 184 | 2. Remove default button styles. 185 | */ 186 | 187 | button, 188 | [type='button'], 189 | [type='reset'], 190 | [type='submit'] { 191 | -webkit-appearance: button; /* 1 */ 192 | background-color: transparent; /* 2 */ 193 | background-image: none; /* 2 */ 194 | } 195 | 196 | /* 197 | Use the modern Firefox focus style for all focusable elements. 198 | */ 199 | 200 | :-moz-focusring { 201 | outline: auto; 202 | } 203 | 204 | /* 205 | Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) 206 | */ 207 | 208 | :-moz-ui-invalid { 209 | box-shadow: none; 210 | } 211 | 212 | /* 213 | Add the correct vertical alignment in Chrome and Firefox. 214 | */ 215 | 216 | progress { 217 | vertical-align: baseline; 218 | } 219 | 220 | /* 221 | Correct the cursor style of increment and decrement buttons in Safari. 222 | */ 223 | 224 | ::-webkit-inner-spin-button, 225 | ::-webkit-outer-spin-button { 226 | height: auto; 227 | } 228 | 229 | /* 230 | 1. Correct the odd appearance in Chrome and Safari. 231 | 2. Correct the outline style in Safari. 232 | */ 233 | 234 | [type='search'] { 235 | -webkit-appearance: textfield; /* 1 */ 236 | outline-offset: -2px; /* 2 */ 237 | } 238 | 239 | /* 240 | Remove the inner padding in Chrome and Safari on macOS. 241 | */ 242 | 243 | ::-webkit-search-decoration { 244 | -webkit-appearance: none; 245 | } 246 | 247 | /* 248 | 1. Correct the inability to style clickable types in iOS and Safari. 249 | 2. Change font properties to `inherit` in Safari. 250 | */ 251 | 252 | ::-webkit-file-upload-button { 253 | -webkit-appearance: button; /* 1 */ 254 | font: inherit; /* 2 */ 255 | } 256 | 257 | /* 258 | Add the correct display in Chrome and Safari. 259 | */ 260 | 261 | summary { 262 | display: list-item; 263 | } 264 | 265 | /* 266 | Removes the default spacing and border for appropriate elements. 267 | */ 268 | 269 | blockquote, 270 | dl, 271 | dd, 272 | h1, 273 | h2, 274 | h3, 275 | h4, 276 | h5, 277 | h6, 278 | hr, 279 | figure, 280 | p, 281 | pre { 282 | margin: 0; 283 | } 284 | 285 | fieldset { 286 | margin: 0; 287 | padding: 0; 288 | } 289 | 290 | legend { 291 | padding: 0; 292 | } 293 | 294 | ol, 295 | ul, 296 | menu { 297 | list-style: none; 298 | margin: 0; 299 | padding: 0; 300 | } 301 | 302 | /* 303 | Prevent resizing textareas horizontally by default. 304 | */ 305 | 306 | textarea { 307 | resize: vertical; 308 | } 309 | 310 | /* 311 | 1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) 312 | 2. Set the default placeholder color to the user's configured gray 400 color. 313 | */ 314 | 315 | input::-moz-placeholder, textarea::-moz-placeholder { 316 | opacity: 1; /* 1 */ 317 | color: #9ca3af; /* 2 */ 318 | } 319 | 320 | input:-ms-input-placeholder, textarea:-ms-input-placeholder { 321 | opacity: 1; /* 1 */ 322 | color: #9ca3af; /* 2 */ 323 | } 324 | 325 | input::placeholder, 326 | textarea::placeholder { 327 | opacity: 1; /* 1 */ 328 | color: #9ca3af; /* 2 */ 329 | } 330 | 331 | /* 332 | Set the default cursor for buttons. 333 | */ 334 | 335 | button, 336 | [role="button"] { 337 | cursor: pointer; 338 | } 339 | 340 | /* 341 | Make sure disabled buttons don't get the pointer cursor. 342 | */ 343 | :disabled { 344 | cursor: default; 345 | } 346 | 347 | /* 348 | 1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) 349 | 2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) 350 | This can trigger a poorly considered lint error in some tools but is included by design. 351 | */ 352 | 353 | img, 354 | svg, 355 | video, 356 | canvas, 357 | audio, 358 | iframe, 359 | embed, 360 | object { 361 | display: block; /* 1 */ 362 | vertical-align: middle; /* 2 */ 363 | } 364 | 365 | /* 366 | Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) 367 | */ 368 | 369 | img, 370 | video { 371 | max-width: 100%; 372 | height: auto; 373 | } 374 | 375 | /* 376 | Ensure the default browser behavior of the `hidden` attribute. 377 | */ 378 | 379 | [hidden] { 380 | display: none; 381 | } 382 | 383 | *, ::before, ::after { 384 | --tw-translate-x: 0; 385 | --tw-translate-y: 0; 386 | --tw-rotate: 0; 387 | --tw-skew-x: 0; 388 | --tw-skew-y: 0; 389 | --tw-scale-x: 1; 390 | --tw-scale-y: 1; 391 | --tw-pan-x: ; 392 | --tw-pan-y: ; 393 | --tw-pinch-zoom: ; 394 | --tw-scroll-snap-strictness: proximity; 395 | --tw-ordinal: ; 396 | --tw-slashed-zero: ; 397 | --tw-numeric-figure: ; 398 | --tw-numeric-spacing: ; 399 | --tw-numeric-fraction: ; 400 | --tw-ring-inset: ; 401 | --tw-ring-offset-width: 0px; 402 | --tw-ring-offset-color: #fff; 403 | --tw-ring-color: rgb(59 130 246 / 0.5); 404 | --tw-ring-offset-shadow: 0 0 #0000; 405 | --tw-ring-shadow: 0 0 #0000; 406 | --tw-shadow: 0 0 #0000; 407 | --tw-shadow-colored: 0 0 #0000; 408 | --tw-blur: ; 409 | --tw-brightness: ; 410 | --tw-contrast: ; 411 | --tw-grayscale: ; 412 | --tw-hue-rotate: ; 413 | --tw-invert: ; 414 | --tw-saturate: ; 415 | --tw-sepia: ; 416 | --tw-drop-shadow: ; 417 | --tw-backdrop-blur: ; 418 | --tw-backdrop-brightness: ; 419 | --tw-backdrop-contrast: ; 420 | --tw-backdrop-grayscale: ; 421 | --tw-backdrop-hue-rotate: ; 422 | --tw-backdrop-invert: ; 423 | --tw-backdrop-opacity: ; 424 | --tw-backdrop-saturate: ; 425 | --tw-backdrop-sepia: ; 426 | } 427 | .absolute { 428 | position: absolute; 429 | } 430 | .top-10 { 431 | top: 2.5rem; 432 | } 433 | .mb-3 { 434 | margin-bottom: 0.75rem; 435 | } 436 | .mb-6 { 437 | margin-bottom: 1.5rem; 438 | } 439 | .mb-1 { 440 | margin-bottom: 0.25rem; 441 | } 442 | .mb-10 { 443 | margin-bottom: 2.5rem; 444 | } 445 | .mr-2 { 446 | margin-right: 0.5rem; 447 | } 448 | .block { 449 | display: block; 450 | } 451 | .inline { 452 | display: inline; 453 | } 454 | .flex { 455 | display: flex; 456 | } 457 | .w-2\/3 { 458 | width: 66.666667%; 459 | } 460 | .w-full { 461 | width: 100%; 462 | } 463 | .w-1\/3 { 464 | width: 33.333333%; 465 | } 466 | .appearance-none { 467 | -webkit-appearance: none; 468 | -moz-appearance: none; 469 | appearance: none; 470 | } 471 | .flex-row { 472 | flex-direction: row; 473 | } 474 | .items-center { 475 | align-items: center; 476 | } 477 | .justify-center { 478 | justify-content: center; 479 | } 480 | .justify-between { 481 | justify-content: space-between; 482 | } 483 | .rounded { 484 | border-radius: 0.25rem; 485 | } 486 | .rounded-lg { 487 | border-radius: 0.5rem; 488 | } 489 | .border { 490 | border-width: 1px; 491 | } 492 | .border-2 { 493 | border-width: 2px; 494 | } 495 | .border-gray-400 { 496 | --tw-border-opacity: 1; 497 | border-color: rgb(156 163 175 / var(--tw-border-opacity)); 498 | } 499 | .border-gray-200 { 500 | --tw-border-opacity: 1; 501 | border-color: rgb(229 231 235 / var(--tw-border-opacity)); 502 | } 503 | .bg-red-500 { 504 | --tw-bg-opacity: 1; 505 | background-color: rgb(239 68 68 / var(--tw-bg-opacity)); 506 | } 507 | .bg-white { 508 | --tw-bg-opacity: 1; 509 | background-color: rgb(255 255 255 / var(--tw-bg-opacity)); 510 | } 511 | .bg-purple-500 { 512 | --tw-bg-opacity: 1; 513 | background-color: rgb(168 85 247 / var(--tw-bg-opacity)); 514 | } 515 | .bg-pink-500 { 516 | --tw-bg-opacity: 1; 517 | background-color: rgb(236 72 153 / var(--tw-bg-opacity)); 518 | } 519 | .p-3 { 520 | padding: 0.75rem; 521 | } 522 | .py-2 { 523 | padding-top: 0.5rem; 524 | padding-bottom: 0.5rem; 525 | } 526 | .px-4 { 527 | padding-left: 1rem; 528 | padding-right: 1rem; 529 | } 530 | .pr-4 { 531 | padding-right: 1rem; 532 | } 533 | .pr-8 { 534 | padding-right: 2rem; 535 | } 536 | .text-xl { 537 | font-size: 1.25rem; 538 | line-height: 1.75rem; 539 | } 540 | .text-lg { 541 | font-size: 1.125rem; 542 | line-height: 1.75rem; 543 | } 544 | .font-bold { 545 | font-weight: 700; 546 | } 547 | .font-extrabold { 548 | font-weight: 800; 549 | } 550 | .leading-tight { 551 | line-height: 1.25; 552 | } 553 | .text-white { 554 | --tw-text-opacity: 1; 555 | color: rgb(255 255 255 / var(--tw-text-opacity)); 556 | } 557 | .text-blue-800 { 558 | --tw-text-opacity: 1; 559 | color: rgb(30 64 175 / var(--tw-text-opacity)); 560 | } 561 | .text-gray-500 { 562 | --tw-text-opacity: 1; 563 | color: rgb(107 114 128 / var(--tw-text-opacity)); 564 | } 565 | .text-gray-700 { 566 | --tw-text-opacity: 1; 567 | color: rgb(55 65 81 / var(--tw-text-opacity)); 568 | } 569 | .underline { 570 | -webkit-text-decoration-line: underline; 571 | text-decoration-line: underline; 572 | } 573 | .shadow { 574 | --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); 575 | --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); 576 | box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); 577 | } 578 | .hover\:border-gray-500:hover { 579 | --tw-border-opacity: 1; 580 | border-color: rgb(107 114 128 / var(--tw-border-opacity)); 581 | } 582 | .hover\:bg-red-400:hover { 583 | --tw-bg-opacity: 1; 584 | background-color: rgb(248 113 113 / var(--tw-bg-opacity)); 585 | } 586 | .hover\:bg-purple-400:hover { 587 | --tw-bg-opacity: 1; 588 | background-color: rgb(192 132 252 / var(--tw-bg-opacity)); 589 | } 590 | .hover\:bg-pink-400:hover { 591 | --tw-bg-opacity: 1; 592 | background-color: rgb(244 114 182 / var(--tw-bg-opacity)); 593 | } 594 | .focus\:border-purple-500:focus { 595 | --tw-border-opacity: 1; 596 | border-color: rgb(168 85 247 / var(--tw-border-opacity)); 597 | } 598 | .focus\:bg-white:focus { 599 | --tw-bg-opacity: 1; 600 | background-color: rgb(255 255 255 / var(--tw-bg-opacity)); 601 | } 602 | .focus\:outline-none:focus { 603 | outline: 2px solid transparent; 604 | outline-offset: 2px; 605 | } 606 | @media (min-width: 768px) { 607 | 608 | .md\:mb-0 { 609 | margin-bottom: 0px; 610 | } 611 | 612 | .md\:flex { 613 | display: flex; 614 | } 615 | 616 | .md\:w-1\/6 { 617 | width: 16.666667%; 618 | } 619 | 620 | .md\:w-5\/6 { 621 | width: 83.333333%; 622 | } 623 | 624 | .md\:text-right { 625 | text-align: right; 626 | } 627 | } 628 | -------------------------------------------------------------------------------- /src/RecurCard.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | 3 | const RecurCard = (props: { uuids: any[]; id: string; item: string }) => { 4 | const [uuids] = useState(props.uuids); 5 | const [settings, setSettings] = useState(logseq.settings); 6 | 7 | const deleteBlocks = async () => { 8 | // delete all blocks 9 | for (let u of uuids) { 10 | await logseq.Editor.removeBlock(u); 11 | } 12 | 13 | // delete entry from settings by matching the id from props and the dateAdded from settings 14 | const recurrencesClone: any[] = settings.recurrences; 15 | recurrencesClone.splice( 16 | recurrencesClone.findIndex((i) => i.dateAdded === props.id), 17 | 1 18 | ); 19 | setSettings((prevSettings) => ({ 20 | ...prevSettings, 21 | recurrences: recurrencesClone, 22 | })); 23 | logseq.hideMainUI(); 24 | logseq.App.showMsg("Blocks deleted successfully!"); 25 | }; 26 | 27 | return ( 28 |
{props.item}
31 |Saved Recurrences
330 | )} 331 |