Update 'login' machanism. Implement triggering store events into useLocalStorage hook

This commit is contained in:
Igor Barcik 2024-02-02 18:09:59 +01:00
parent 3ea8f1fd1b
commit ad34d95e7b
Signed by: biggy
GPG Key ID: EA4CE0D1E2A6DC98
14 changed files with 266 additions and 267 deletions

BIN
bun.lockb

Binary file not shown.

View File

@ -263,8 +263,8 @@
},
{
"type": "text",
"version": 859,
"versionNonce": 531548862,
"version": 860,
"versionNonce": 1169460443,
"isDeleted": false,
"id": "97fLf76gEdKS_GvQ6ALpU",
"fillStyle": "solid",
@ -286,7 +286,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007569,
"updated": 1706874741849,
"link": null,
"locked": false,
"fontSize": 36,
@ -459,8 +459,8 @@
},
{
"type": "text",
"version": 170,
"versionNonce": 260491298,
"version": 171,
"versionNonce": 122389077,
"isDeleted": false,
"id": "lIMGkmHcJPDoBybM182aS",
"fillStyle": "solid",
@ -480,7 +480,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007569,
"updated": 1706874741849,
"link": null,
"locked": false,
"fontSize": 20,
@ -531,8 +531,8 @@
},
{
"type": "text",
"version": 843,
"versionNonce": 658686718,
"version": 844,
"versionNonce": 115620219,
"isDeleted": false,
"id": "czL3rOtvV4NqzRGs0GVjq",
"fillStyle": "cross-hatch",
@ -554,7 +554,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007570,
"updated": 1706874741850,
"link": null,
"locked": false,
"fontSize": 16,
@ -569,8 +569,8 @@
},
{
"type": "text",
"version": 613,
"versionNonce": 1971155938,
"version": 614,
"versionNonce": 1941073845,
"isDeleted": false,
"id": "UyOYTvi_ehfK_7ZeUqKNh",
"fillStyle": "cross-hatch",
@ -592,7 +592,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007570,
"updated": 1706874741850,
"link": null,
"locked": false,
"fontSize": 16,
@ -653,8 +653,8 @@
},
{
"type": "text",
"version": 585,
"versionNonce": 1110291262,
"version": 586,
"versionNonce": 716526107,
"isDeleted": false,
"id": "b5cYSaZuXHVCg_wgIGqyf",
"fillStyle": "cross-hatch",
@ -677,7 +677,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007570,
"updated": 1706874741852,
"link": null,
"locked": false,
"fontSize": 16,
@ -724,8 +724,8 @@
},
{
"type": "text",
"version": 721,
"versionNonce": 120104866,
"version": 722,
"versionNonce": 60076309,
"isDeleted": false,
"id": "vK17TLw3lSPYKis4oRv10",
"fillStyle": "cross-hatch",
@ -748,7 +748,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007571,
"updated": 1706874741852,
"link": null,
"locked": false,
"fontSize": 16,
@ -795,8 +795,8 @@
},
{
"type": "text",
"version": 771,
"versionNonce": 1523620734,
"version": 772,
"versionNonce": 840586939,
"isDeleted": false,
"id": "YaQApvBsokdg3uc1F-yqm",
"fillStyle": "cross-hatch",
@ -819,7 +819,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007571,
"updated": 1706874741852,
"link": null,
"locked": false,
"fontSize": 16,
@ -866,8 +866,8 @@
},
{
"type": "text",
"version": 896,
"versionNonce": 1823957858,
"version": 897,
"versionNonce": 1416087157,
"isDeleted": false,
"id": "DpHSN121nXDlx6NRNdrhz",
"fillStyle": "cross-hatch",
@ -889,7 +889,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007571,
"updated": 1706874741853,
"link": null,
"locked": false,
"fontSize": 16,
@ -904,8 +904,8 @@
},
{
"type": "text",
"version": 575,
"versionNonce": 1735162814,
"version": 576,
"versionNonce": 1538639707,
"isDeleted": false,
"id": "dD_ckfrdnLxCAC6Xr96mr",
"fillStyle": "cross-hatch",
@ -927,7 +927,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007571,
"updated": 1706874741853,
"link": null,
"locked": false,
"fontSize": 16,
@ -2046,8 +2046,8 @@
},
{
"type": "text",
"version": 613,
"versionNonce": 1886955298,
"version": 614,
"versionNonce": 955330517,
"isDeleted": false,
"id": "TWGywr2MmOeMW4gs8000_",
"fillStyle": "solid",
@ -2067,7 +2067,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007572,
"updated": 1706874741853,
"link": null,
"locked": false,
"fontSize": 20,
@ -2111,8 +2111,8 @@
},
{
"type": "text",
"version": 642,
"versionNonce": 1847743486,
"version": 643,
"versionNonce": 1843012603,
"isDeleted": false,
"id": "xBzNkZFVCqb_jKgjmeqPR",
"fillStyle": "solid",
@ -2132,7 +2132,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007572,
"updated": 1706874741854,
"link": null,
"locked": false,
"fontSize": 36,
@ -2350,8 +2350,8 @@
},
{
"type": "text",
"version": 659,
"versionNonce": 987460322,
"version": 660,
"versionNonce": 256273717,
"isDeleted": false,
"id": "ZROg7dmoN-YH48DAzVkVm",
"fillStyle": "solid",
@ -2371,7 +2371,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007573,
"updated": 1706874741854,
"link": null,
"locked": false,
"fontSize": 16,
@ -2596,8 +2596,8 @@
},
{
"type": "text",
"version": 787,
"versionNonce": 150152254,
"version": 788,
"versionNonce": 1082780827,
"isDeleted": false,
"id": "27g6d6zkbFMakk4yjYlMe",
"fillStyle": "solid",
@ -2622,7 +2622,7 @@
"type": "arrow"
}
],
"updated": 1706857007573,
"updated": 1706874741854,
"link": null,
"locked": false,
"fontSize": 16,
@ -2637,8 +2637,8 @@
},
{
"type": "text",
"version": 821,
"versionNonce": 242140834,
"version": 822,
"versionNonce": 1456275093,
"isDeleted": false,
"id": "2n275KB8dVMGKR5z78AzE",
"fillStyle": "solid",
@ -2658,7 +2658,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007573,
"updated": 1706874741854,
"link": null,
"locked": false,
"fontSize": 16,
@ -2673,8 +2673,8 @@
},
{
"type": "text",
"version": 858,
"versionNonce": 1774185598,
"version": 859,
"versionNonce": 125280571,
"isDeleted": false,
"id": "HtmF7uDtsZerEiCY9Wrr2",
"fillStyle": "solid",
@ -2694,7 +2694,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007573,
"updated": 1706874741855,
"link": null,
"locked": false,
"fontSize": 16,
@ -2867,8 +2867,8 @@
},
{
"type": "text",
"version": 425,
"versionNonce": 65118818,
"version": 426,
"versionNonce": 104489973,
"isDeleted": false,
"id": "lHG7_KEcLq8Jnlob9oJs-",
"fillStyle": "cross-hatch",
@ -2893,7 +2893,7 @@
"type": "arrow"
}
],
"updated": 1706857007574,
"updated": 1706874741855,
"link": null,
"locked": false,
"fontSize": 16,
@ -2960,8 +2960,8 @@
},
{
"type": "text",
"version": 639,
"versionNonce": 1581886654,
"version": 640,
"versionNonce": 1543881179,
"isDeleted": false,
"id": "DLa0lPVXghvlzyQUiLnzi",
"fillStyle": "cross-hatch",
@ -2986,7 +2986,7 @@
"type": "arrow"
}
],
"updated": 1706857007574,
"updated": 1706874741855,
"link": null,
"locked": false,
"fontSize": 16,
@ -3097,8 +3097,8 @@
},
{
"type": "text",
"version": 867,
"versionNonce": 1174603298,
"version": 868,
"versionNonce": 563354965,
"isDeleted": false,
"id": "X6ZL8ZTMvlKjWI3ba1hvI",
"fillStyle": "solid",
@ -3118,7 +3118,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007574,
"updated": 1706874741856,
"link": null,
"locked": false,
"fontSize": 16,
@ -3167,8 +3167,8 @@
},
{
"type": "text",
"version": 761,
"versionNonce": 1412523262,
"version": 762,
"versionNonce": 122080891,
"isDeleted": false,
"id": "ZEo99QAbAO47p8--HBfd-",
"fillStyle": "solid",
@ -3188,7 +3188,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007574,
"updated": 1706874741856,
"link": null,
"locked": false,
"fontSize": 20,
@ -3203,8 +3203,8 @@
},
{
"type": "text",
"version": 808,
"versionNonce": 1304556002,
"version": 809,
"versionNonce": 271559349,
"isDeleted": false,
"id": "CkCABc8KuyOn0P-BdVmd6",
"fillStyle": "solid",
@ -3224,7 +3224,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007575,
"updated": 1706874741856,
"link": null,
"locked": false,
"fontSize": 20,
@ -3239,8 +3239,8 @@
},
{
"type": "text",
"version": 1019,
"versionNonce": 1559762238,
"version": 1020,
"versionNonce": 201148187,
"isDeleted": false,
"id": "myQuI1HagifoucfsqyYKJ",
"fillStyle": "solid",
@ -3260,7 +3260,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007575,
"updated": 1706874741856,
"link": null,
"locked": false,
"fontSize": 20,
@ -3275,8 +3275,8 @@
},
{
"type": "text",
"version": 815,
"versionNonce": 506291618,
"version": 816,
"versionNonce": 850562069,
"isDeleted": false,
"id": "-Yf8k6Dj3Lj-jOgr249Af",
"fillStyle": "solid",
@ -3296,7 +3296,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007575,
"updated": 1706874741857,
"link": null,
"locked": false,
"fontSize": 20,
@ -3311,8 +3311,8 @@
},
{
"type": "text",
"version": 852,
"versionNonce": 838778238,
"version": 853,
"versionNonce": 1889250235,
"isDeleted": false,
"id": "IoXP3HH9PXErWUBPpkQME",
"fillStyle": "solid",
@ -3332,7 +3332,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007575,
"updated": 1706874741857,
"link": null,
"locked": false,
"fontSize": 20,
@ -3347,8 +3347,8 @@
},
{
"type": "text",
"version": 1072,
"versionNonce": 7627106,
"version": 1073,
"versionNonce": 957497717,
"isDeleted": false,
"id": "NFjnbU6And4fMiUyl8kGC",
"fillStyle": "solid",
@ -3368,7 +3368,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007575,
"updated": 1706874741857,
"link": null,
"locked": false,
"fontSize": 20,
@ -3383,8 +3383,8 @@
},
{
"type": "text",
"version": 1111,
"versionNonce": 948329918,
"version": 1112,
"versionNonce": 1229225051,
"isDeleted": false,
"id": "87zM95Ly4uuN74flGhu5I",
"fillStyle": "solid",
@ -3404,7 +3404,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007576,
"updated": 1706874741857,
"link": null,
"locked": false,
"fontSize": 20,
@ -3851,8 +3851,8 @@
},
{
"type": "text",
"version": 781,
"versionNonce": 1072031010,
"version": 782,
"versionNonce": 949242581,
"isDeleted": false,
"id": "bFWjBJqnUAi5N3n2ZWux_",
"fillStyle": "solid",
@ -3872,7 +3872,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007576,
"updated": 1706874741858,
"link": null,
"locked": false,
"fontSize": 20,
@ -4008,8 +4008,8 @@
},
{
"type": "text",
"version": 1092,
"versionNonce": 95417854,
"version": 1093,
"versionNonce": 30030075,
"isDeleted": false,
"id": "AngCsxgQFZ8FlJDffEu--",
"fillStyle": "solid",
@ -4029,7 +4029,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007576,
"updated": 1706874741858,
"link": null,
"locked": false,
"fontSize": 36,
@ -4044,8 +4044,8 @@
},
{
"type": "text",
"version": 1123,
"versionNonce": 1710289122,
"version": 1124,
"versionNonce": 30287925,
"isDeleted": false,
"id": "y_U_FPL_9JR3gVTy88NCf",
"fillStyle": "solid",
@ -4065,7 +4065,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007577,
"updated": 1706874741858,
"link": null,
"locked": false,
"fontSize": 28,
@ -4080,8 +4080,8 @@
},
{
"type": "text",
"version": 1158,
"versionNonce": 1652327998,
"version": 1159,
"versionNonce": 1739547035,
"isDeleted": false,
"id": "mOf1HdeIlUxFfE7a1VcGR",
"fillStyle": "solid",
@ -4101,7 +4101,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007577,
"updated": 1706874741859,
"link": null,
"locked": false,
"fontSize": 28,
@ -4116,8 +4116,8 @@
},
{
"type": "text",
"version": 1090,
"versionNonce": 1982104738,
"version": 1091,
"versionNonce": 916806037,
"isDeleted": false,
"id": "DR4VwW8oFIQ4bTi23EuNf",
"fillStyle": "solid",
@ -4137,7 +4137,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007577,
"updated": 1706874741859,
"link": null,
"locked": false,
"fontSize": 28,
@ -4152,8 +4152,8 @@
},
{
"type": "text",
"version": 771,
"versionNonce": 1338838654,
"version": 772,
"versionNonce": 1948677691,
"isDeleted": false,
"id": "J9irHVDB_SLk4-2nUzUsU",
"fillStyle": "solid",
@ -4173,7 +4173,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007578,
"updated": 1706874741859,
"link": null,
"locked": false,
"fontSize": 16,
@ -4188,8 +4188,8 @@
},
{
"type": "text",
"version": 795,
"versionNonce": 707764322,
"version": 796,
"versionNonce": 542072565,
"isDeleted": false,
"id": "c19gjwN8b8L3I0q4go5Bf",
"fillStyle": "cross-hatch",
@ -4209,7 +4209,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007578,
"updated": 1706874741859,
"link": null,
"locked": false,
"fontSize": 16,
@ -4224,8 +4224,8 @@
},
{
"type": "text",
"version": 826,
"versionNonce": 174231230,
"version": 827,
"versionNonce": 1444017883,
"isDeleted": false,
"id": "oW9r6Oj1KNFEDfDrTobE0",
"fillStyle": "cross-hatch",
@ -4245,7 +4245,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007578,
"updated": 1706874741860,
"link": null,
"locked": false,
"fontSize": 16,
@ -4260,8 +4260,8 @@
},
{
"type": "text",
"version": 853,
"versionNonce": 769737762,
"version": 854,
"versionNonce": 1162983509,
"isDeleted": false,
"id": "3FPR-httcvZJQOpdp5nlq",
"fillStyle": "cross-hatch",
@ -4281,7 +4281,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007578,
"updated": 1706874741860,
"link": null,
"locked": false,
"fontSize": 16,
@ -4296,8 +4296,8 @@
},
{
"type": "text",
"version": 828,
"versionNonce": 249431806,
"version": 829,
"versionNonce": 1006920571,
"isDeleted": false,
"id": "Q5UuTLzxJDwFmgRxTm2kC",
"fillStyle": "cross-hatch",
@ -4317,7 +4317,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007578,
"updated": 1706874741860,
"link": null,
"locked": false,
"fontSize": 16,
@ -4332,8 +4332,8 @@
},
{
"type": "text",
"version": 575,
"versionNonce": 1529376738,
"version": 576,
"versionNonce": 1065477557,
"isDeleted": false,
"id": "Wz3mVdVr-D1sldEkuMc-C",
"fillStyle": "solid",
@ -4353,7 +4353,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007579,
"updated": 1706874741860,
"link": null,
"locked": false,
"fontSize": 16,
@ -4368,8 +4368,8 @@
},
{
"type": "text",
"version": 703,
"versionNonce": 499152702,
"version": 704,
"versionNonce": 1581267995,
"isDeleted": false,
"id": "5BRLdUcImdXd-sAkul1NW",
"fillStyle": "solid",
@ -4389,7 +4389,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007579,
"updated": 1706874741860,
"link": null,
"locked": false,
"fontSize": 16,
@ -4404,8 +4404,8 @@
},
{
"type": "text",
"version": 735,
"versionNonce": 1981031330,
"version": 736,
"versionNonce": 1376085781,
"isDeleted": false,
"id": "NIRZl827FKmclhhKsmfJG",
"fillStyle": "solid",
@ -4425,7 +4425,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007579,
"updated": 1706874741861,
"link": null,
"locked": false,
"fontSize": 16,
@ -4440,8 +4440,8 @@
},
{
"type": "text",
"version": 767,
"versionNonce": 1063968638,
"version": 768,
"versionNonce": 1220018363,
"isDeleted": false,
"id": "nwfWQopAIVcO11jOf_vRF",
"fillStyle": "solid",
@ -4461,7 +4461,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007579,
"updated": 1706874741861,
"link": null,
"locked": false,
"fontSize": 16,
@ -4592,8 +4592,8 @@
},
{
"type": "text",
"version": 702,
"versionNonce": 1758682978,
"version": 703,
"versionNonce": 1062321269,
"isDeleted": false,
"id": "rzBAAYkybbEjgW-X1nldy",
"fillStyle": "solid",
@ -4613,7 +4613,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007580,
"updated": 1706874741861,
"link": null,
"locked": false,
"fontSize": 28,
@ -4628,8 +4628,8 @@
},
{
"type": "text",
"version": 718,
"versionNonce": 1209941950,
"version": 719,
"versionNonce": 1695428955,
"isDeleted": false,
"id": "oxovXJjAobce88xbeLU8R",
"fillStyle": "solid",
@ -4651,7 +4651,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007580,
"updated": 1706874741861,
"link": null,
"locked": false,
"fontSize": 28,
@ -4666,8 +4666,8 @@
},
{
"type": "text",
"version": 707,
"versionNonce": 2142577442,
"version": 708,
"versionNonce": 1596745173,
"isDeleted": false,
"id": "bsapaFzL8TDKJ9MbrtJEa",
"fillStyle": "solid",
@ -4689,7 +4689,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007580,
"updated": 1706874741862,
"link": null,
"locked": false,
"fontSize": 28,
@ -4704,8 +4704,8 @@
},
{
"type": "text",
"version": 754,
"versionNonce": 1543215102,
"version": 755,
"versionNonce": 1150635515,
"isDeleted": false,
"id": "98b_U589sHYl_q_k7dRbc",
"fillStyle": "solid",
@ -4729,7 +4729,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007580,
"updated": 1706874741862,
"link": null,
"locked": false,
"fontSize": 28,
@ -4744,8 +4744,8 @@
},
{
"type": "text",
"version": 452,
"versionNonce": 623406818,
"version": 453,
"versionNonce": 1957356341,
"isDeleted": false,
"id": "PMAVESvlWDWmWj93013fH",
"fillStyle": "solid",
@ -4765,7 +4765,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007581,
"updated": 1706874741862,
"link": null,
"locked": false,
"fontSize": 28,
@ -4838,8 +4838,8 @@
},
{
"type": "text",
"version": 98,
"versionNonce": 1929635902,
"version": 99,
"versionNonce": 709875355,
"isDeleted": false,
"id": "IQb1FgS9Z9XPkqAlLeR35",
"fillStyle": "solid",
@ -4859,7 +4859,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007581,
"updated": 1706874741863,
"link": null,
"locked": false,
"fontSize": 28,
@ -4874,8 +4874,8 @@
},
{
"type": "text",
"version": 138,
"versionNonce": 498877090,
"version": 139,
"versionNonce": 1144173717,
"isDeleted": false,
"id": "uoXtQ_5jmNBJ6aOSh8TG7",
"fillStyle": "solid",
@ -4895,7 +4895,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007581,
"updated": 1706874741863,
"link": null,
"locked": false,
"fontSize": 28,
@ -4910,8 +4910,8 @@
},
{
"type": "text",
"version": 122,
"versionNonce": 1561866366,
"version": 123,
"versionNonce": 1425034043,
"isDeleted": false,
"id": "YKlce3NhSAO2cOpVFM--B",
"fillStyle": "solid",
@ -4931,7 +4931,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007583,
"updated": 1706874741863,
"link": null,
"locked": false,
"fontSize": 16,
@ -4946,8 +4946,8 @@
},
{
"type": "text",
"version": 163,
"versionNonce": 1142922850,
"version": 164,
"versionNonce": 1769560565,
"isDeleted": false,
"id": "j_Vkhf5mLxVsrltY5uihc",
"fillStyle": "solid",
@ -4967,7 +4967,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007583,
"updated": 1706874741863,
"link": null,
"locked": false,
"fontSize": 16,
@ -4982,8 +4982,8 @@
},
{
"type": "text",
"version": 795,
"versionNonce": 1173975230,
"version": 796,
"versionNonce": 148450267,
"isDeleted": false,
"id": "u50Phb99MTDiTPuc37JeQ",
"fillStyle": "solid",
@ -5003,7 +5003,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007583,
"updated": 1706874741864,
"link": null,
"locked": false,
"fontSize": 28,
@ -5142,8 +5142,8 @@
},
{
"type": "text",
"version": 775,
"versionNonce": 1159823906,
"version": 776,
"versionNonce": 1837388629,
"isDeleted": false,
"id": "wNiAAV6zgGuZTvY5864FZ",
"fillStyle": "solid",
@ -5163,7 +5163,7 @@
"frameId": null,
"roundness": null,
"boundElements": [],
"updated": 1706857007584,
"updated": 1706874741864,
"link": null,
"locked": false,
"fontSize": 36,
@ -5371,8 +5371,8 @@
},
{
"type": "text",
"version": 112,
"versionNonce": 961063166,
"version": 113,
"versionNonce": 1511848059,
"isDeleted": false,
"id": "vR3E88Ypr64zTJDIqP-Pw",
"fillStyle": "solid",
@ -5397,7 +5397,7 @@
"type": "arrow"
}
],
"updated": 1706857007584,
"updated": 1706874741864,
"link": null,
"locked": false,
"fontSize": 16,

View File

@ -3,17 +3,12 @@
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@hookform/resolvers": "^3.3.2",
"@radix-ui/react-popover": "^1.0.7",
"@radix-ui/react-tooltip": "^1.0.7",
"@tanstack/react-table": "^8.10.7",
"axios": "^1.6.1",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"daisyui": "latest",
"echarts": "^5.4.3",
"i18next": "^23.7.18",
"i18next-browser-languagedetector": "^7.2.0",
"lucide-react": "^0.320.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.48.2",

View File

@ -1,7 +1,3 @@
// TODO: - [x] Rewrite new switch generating function based on custom routes object
// TODO: - [x] Make condition for base path in Router, for "/" in main.base_path don't add to Router
// TODO: - [x] Rewrite DevControlPanel to use custom routes object
import { useEffect } from "react";
import { useTranslation } from "react-i18next";
import { Outlet, useLocation, useNavigate } from "react-router-dom";
@ -15,16 +11,28 @@ function App() {
const navigate = useNavigate();
const location = useLocation();
// Effect to change language based on state
useEffect(() => {
// Load language from local storage
i18n.changeLanguage(language);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [language]);
// Redirect to login page if not logged in
// Here was a problem with detecting updates of isLoggedIn state. Solution was to manually trigger events on storage change when storage was updated.
// Refer to useLocalStorage hook in ./hooks/useLocalStorage.ts at line 39 for more details
useEffect(() => {
if (!isLoggedIn && location.pathname !== "/login") {
// Redirections based on login state
if (!isLoggedIn) {
console.log("NOT LOGGED IN");
navigate("/login");
}
}, [isLoggedIn]);
if (isLoggedIn && location.pathname === "/login") {
console.log("LOGGED IN");
navigate("/orders");
} else {
console.log(`ALREADY ${!isLoggedIn ? "NOT " : ""}LOGGED IN`);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isLoggedIn, navigate]);
// Conditional rendering based on base path
return <Outlet />;

View File

@ -19,10 +19,10 @@ const MenuContainer: React.FC<OverlayButtonContainerProps> = ({
}) => {
const chooseContainerPosition = useCallback(() => {
const commonClasses = `z-50 menu bg-base-300 rounded-box gap-4 absolute ${horizontal ? "menu-horizontal" : ""} `;
if (position === "top-left") return commonClasses + "top-4 left-4";
if (position === "top-right") return commonClasses + "top-4 right-4";
if (position === "bottom-left") return commonClasses + "bottom-4 left-4";
if (position === "bottom-right") return commonClasses + "bottom-4 right-4";
if (position === "top-left") return commonClasses + "top-2 left-2";
if (position === "top-right") return commonClasses + "top-2 right-2";
if (position === "bottom-left") return commonClasses + "bottom-2 left-2";
if (position === "bottom-right") return commonClasses + "bottom-2 right-2";
}, [horizontal, position]);
const overlayButtonContainer = () => {

View File

@ -1,21 +1,21 @@
import { useTranslation } from "react-i18next";
import { FiLogOut } from "react-icons/fi";
import { useNavigate } from "react-router-dom";
import useLocalStorage from "../../hooks/useLocalStorage";
import RoundButtonBase from "../atoms/RoundButtonBase";
import IconBase from "../molecules/IconBase";
const LogoutButton = () => {
const [, setIsLoggedIn] = useLocalStorage("isLoggedIn", false);
const navigate = useNavigate();
const { t } = useTranslation();
const handleLogout = () => {
setIsLoggedIn(false);
};
return (
<RoundButtonBase
buttonProps={{
onClick: () => {
setIsLoggedIn(false);
navigate("/login");
},
onClick: handleLogout,
}}
tooltipText={t("button.action.logout")}
>

View File

@ -1,40 +0,0 @@
import { useTranslation } from "react-i18next";
import MenuContainer from "../atoms/MenuContainer";
import LogoutButton from "../organisms/LogoutButton";
import ThemeButton from "../organisms/ThemeButton";
import LanguageButton from "../organisms/LanguageButton";
export interface HomePageTemplateProps {
buttonLabel: string;
buttonOnClick: () => void;
value: number;
}
const HomePageTemplate = (props: HomePageTemplateProps) => {
const { t } = useTranslation();
return (
<div className="hero">
<MenuContainer position="top-right" tooltipPosition="left">
<ThemeButton />
<LogoutButton />
<LanguageButton />
</MenuContainer>
<div className="hero-content prose flex-col">
<h1>HomePage</h1>
<div className="card card-bordered shadow-2xl bg-base-100 text-base-content items-center">
<div className="card-body">
{t("homePage.counter")}: {props.value}
</div>
<button
className="btn btn-sm btn-accent absolute w-fit -bottom-4"
onClick={props.buttonOnClick}
>
{props.buttonLabel}
</button>
</div>
</div>
</div>
);
};
export default HomePageTemplate;

View File

@ -51,10 +51,10 @@ const LoginPageTemplate = ({
</div>
<div className="form-control mt-6">
<input
type="submit"
value={t("button.action.login")}
className="btn btn-primary"
onClick={handleLogin}
defaultValue={t("button.action.login")}
type="button"
/>
</div>
</form>

View File

@ -1,26 +1,18 @@
import { useState } from "react";
import { useEffect, useState } from "react";
/**
* Custom hook for persisting state in local storage.
* useLocalStorage is a custom hook that allows you to work with LocalStorage like useState.
* It also syncs data between tabs in real-time.
*
* This hook works similarly to the standard `useState` hook but also stores the state in local storage,
* allowing the state to persist across browser sessions. The state is initialized from local storage
* if it exists; otherwise, it falls back to the provided initial value.
* @param {string} key - A unique identifier for the localStorage entry.
* @param {T} initialValue - The initial value for the localStorage entry.
*
* @template T The type of the value to be stored.
* @param {string} key The key under which the value is stored in local storage.
* @param {T} initialValue The initial value to be used if there is no item in local storage with the given key.
* @returns {[T, (value: T | ((val: T) => T)) => void]} A tuple containing:
* - `storedValue`: the current value stored in local storage.
* - `setValue`: a function to set the value, which updates both the local state and local storage.
*
* @example
* const [name, setName] = useLocalStorage<string>("name", "Initial Name");
* // Use setName to update the name and it will be stored in local storage.
* @returns {Array} An array where the first item is the stored value and the second item is a setter function.
*/
const useLocalStorage = <T>(
key: string,
initialValue: T,
): [T, (value: T) => void] => {
// Store the initial value in localStorage or return the current value
const [storedValue, setStoredValue] = useState<T>(() => {
try {
const item = window.localStorage.getItem(key);
@ -31,16 +23,45 @@ const useLocalStorage = <T>(
}
});
// Define a setter function for the storedValue
const setValue = (value: T) => {
try {
const valueToStore = value instanceof Function ? value(storedValue) : value;
setStoredValue(valueToStore);
// Store the new value in localStorage
window.localStorage.setItem(key, JSON.stringify(valueToStore));
// Manually trigger a storage event
const storageEvent = new StorageEvent("storage", {
key: key,
oldValue: JSON.stringify(storedValue),
newValue: JSON.stringify(valueToStore),
storageArea: localStorage,
});
window.dispatchEvent(storageEvent);
} catch (error) {
console.log(error);
}
};
// Add an event listener for the storage event
useEffect(() => {
const handleStorageChange = (e: StorageEvent) => {
if (e.key === key && e.newValue !== null) {
setStoredValue(JSON.parse(e.newValue));
}
};
window.addEventListener("storage", handleStorageChange);
// Cleanup function
return () => {
window.removeEventListener("storage", handleStorageChange);
};
}, [key]);
// Return the stored value and the setter function
return [storedValue, setValue];
};

View File

@ -1,27 +0,0 @@
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { Outlet } from "react-router-dom";
import HomePageTemplate from "../components/templates/HomePageTemplate";
const HomePage = () => {
const [counter, setCounter] = useState(0);
const { t } = useTranslation();
return (
<>
<HomePageTemplate
buttonLabel={t("homePage.click_me", "Click me!!!")}
buttonOnClick={() => {
if (counter >= 10) {
setCounter(0);
return;
} else setCounter(counter + 1);
}}
value={counter}
/>
<Outlet />
</>
);
};
export default HomePage;

View File

@ -7,11 +7,11 @@ const LoginPage = () => {
const navigate = useNavigate();
const handleLogin = () => {
setIsLoggedIn(true);
navigate("/");
};
const onClickGetStarted = () => {
navigate("/more");
};
return (
<LoginPageTemplate
handleLogin={handleLogin}

View File

@ -0,0 +1,22 @@
import { Outlet } from "react-router-dom";
import MenuContainer from "../components/atoms/MenuContainer";
import LanguageButton from "../components/organisms/LanguageButton";
import LogoutButton from "../components/organisms/LogoutButton";
import ThemeButton from "../components/organisms/ThemeButton";
/**
* General navigation buttons
*/
const MainOverlayPage = () => {
return (
<div className="m-auto p-0 w-11/12 h-full">
<MenuContainer position="top-right" tooltipPosition="left">
<ThemeButton />
<LogoutButton />
<LanguageButton />
</MenuContainer>
<Outlet />
</div>
);
};
export default MainOverlayPage;

12
src/pages/OrdersPage.tsx Normal file
View File

@ -0,0 +1,12 @@
import { useEffect } from "react";
import { useLoaderData } from "react-router-dom";
const OrdersPage = () => {
const users = useLoaderData();
useEffect(() => {
console.log("OrdersPage -> useEffect");
});
return <div>{JSON.stringify(users)}</div>;
};
export default OrdersPage;

View File

@ -1,8 +1,9 @@
import HomePage from "../pages/HomePage";
import LoginPage from "../pages/LoginPage";
import { RouteObject } from "react-router-dom";
import NotFound_404 from "../pages/NotFound_404";
import App from "../App";
import LoginPage from "../pages/LoginPage";
import MainOverlayPage from "../pages/MainOverlayPage";
import NotFound_404 from "../pages/NotFound_404";
import OrdersPage from "../pages/OrdersPage";
// ----- ROUTES CONFIGURATION -----
// Configuration of the application's route structure
@ -12,11 +13,18 @@ const routes: RouteObject[] = [
element: <App />,
children: [
{
path: "/",
element: <HomePage />,
element: <MainOverlayPage />,
children: [
{
path: "/orders",
element: <OrdersPage />,
loader: () =>
fetch("https://dummyjson.com/users").then((res) => res.json()),
},
],
},
{
path: "login",
path: "/login",
element: <LoginPage />,
},
],