From d3b792dc1d4df7835c6f75fdb66faf93f9dba12b Mon Sep 17 00:00:00 2001 From: gibbyb Date: Sat, 30 Nov 2024 12:48:48 -0600 Subject: [PATCH] Add more pages using v0 --- package.json | 1 + pnpm-lock.yaml | 257 ++++++++++++++++ src/app/account/billtracker/page.tsx | 161 +++++++++- src/app/account/billtracker/page.tsx.bak | 19 ++ src/app/account/documents/page.tsx | 63 ++++ src/app/account/messages/page.tsx | 70 +++++ src/app/account/payments/page.tsx | 80 +++++ src/app/account/workorders/page.tsx | 135 +++++++++ src/app/admin/documents/page.tsx | 223 ++++++++++++++ src/app/admin/layout.tsx | 62 ++++ src/app/admin/messages/page.tsx | 249 ++++++++++++++++ src/app/admin/page.tsx | 174 +++++++++++ src/app/admin/payments/page.tsx | 269 +++++++++++++++++ src/app/admin/properties/page.tsx | 218 ++++++++++++++ src/app/admin/tenants/page.tsx | 236 +++++++++++++++ src/app/admin/workorders/page.tsx | 298 ++++++++++++++++++ src/components/ui/badge.tsx | 36 +++ src/components/ui/calendar.tsx | 66 ++++ src/components/ui/chart.tsx | 365 +++++++++++++++++++++++ 19 files changed, 2966 insertions(+), 16 deletions(-) mode change 100755 => 100644 src/app/account/billtracker/page.tsx create mode 100755 src/app/account/billtracker/page.tsx.bak create mode 100644 src/app/admin/documents/page.tsx create mode 100644 src/app/admin/layout.tsx create mode 100644 src/app/admin/messages/page.tsx create mode 100644 src/app/admin/page.tsx create mode 100644 src/app/admin/payments/page.tsx create mode 100644 src/app/admin/properties/page.tsx create mode 100644 src/app/admin/tenants/page.tsx create mode 100644 src/app/admin/workorders/page.tsx create mode 100644 src/components/ui/badge.tsx create mode 100644 src/components/ui/calendar.tsx create mode 100644 src/components/ui/chart.tsx diff --git a/package.json b/package.json index 3260796..5c82ae7 100755 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "react-day-picker": "8.10.1", "react-dom": "^18.3.1", "react-hook-form": "^7.52.2", + "recharts": "^2.13.3", "server-only": "^0.0.1", "sonner": "^1.5.0", "tailwind-merge": "^2.4.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 136cfe0..fcd5445 100755 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -113,6 +113,9 @@ importers: react-hook-form: specifier: ^7.52.2 version: 7.52.2(react@18.3.1) + recharts: + specifier: ^2.13.3 + version: 2.13.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) server-only: specifier: ^0.0.1 version: 0.0.1 @@ -1489,6 +1492,33 @@ packages: '@types/cookie@0.6.0': resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} + '@types/d3-array@3.2.1': + resolution: {integrity: sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==} + + '@types/d3-color@3.1.3': + resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==} + + '@types/d3-ease@3.0.2': + resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==} + + '@types/d3-interpolate@3.0.4': + resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==} + + '@types/d3-path@3.1.0': + resolution: {integrity: sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==} + + '@types/d3-scale@4.0.8': + resolution: {integrity: sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==} + + '@types/d3-shape@3.1.6': + resolution: {integrity: sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==} + + '@types/d3-time@3.0.4': + resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==} + + '@types/d3-timer@3.0.2': + resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==} + '@types/eslint@8.56.11': resolution: {integrity: sha512-sVBpJMf7UPo/wGecYOpk2aQya2VUGeHhe38WG7/mN5FufNSubf5VT9Uh9Uyp8/eLJpu1/tuhJ/qTo4mhSB4V4Q==} @@ -1829,6 +1859,50 @@ packages: csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + d3-array@3.2.4: + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} + engines: {node: '>=12'} + + d3-color@3.1.0: + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} + engines: {node: '>=12'} + + d3-ease@3.0.1: + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} + engines: {node: '>=12'} + + d3-format@3.1.0: + resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==} + engines: {node: '>=12'} + + d3-interpolate@3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + engines: {node: '>=12'} + + d3-path@3.1.0: + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} + engines: {node: '>=12'} + + d3-scale@4.0.2: + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + engines: {node: '>=12'} + + d3-shape@3.2.0: + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} + engines: {node: '>=12'} + + d3-time-format@4.1.0: + resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} + engines: {node: '>=12'} + + d3-time@3.1.0: + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} + engines: {node: '>=12'} + + d3-timer@3.0.1: + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} + engines: {node: '>=12'} + d@1.0.2: resolution: {integrity: sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==} engines: {node: '>=0.12'} @@ -1868,6 +1942,9 @@ packages: supports-color: optional: true + decimal.js-light@2.5.1: + resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==} + deep-equal@2.2.3: resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==} engines: {node: '>= 0.4'} @@ -1911,6 +1988,9 @@ packages: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} + dom-helpers@5.2.1: + resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} + dotenv@16.4.5: resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} engines: {node: '>=12'} @@ -2208,12 +2288,19 @@ packages: event-emitter@0.3.5: resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==} + eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + ext@1.7.0: resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-equals@5.0.1: + resolution: {integrity: sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==} + engines: {node: '>=6.0.0'} + fast-glob@3.3.2: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} @@ -2393,6 +2480,10 @@ packages: resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} engines: {node: '>= 0.4'} + internmap@2.0.3: + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} + engines: {node: '>=12'} + invariant@2.2.4: resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} @@ -2629,6 +2720,9 @@ packages: lodash.throttle@4.1.1: resolution: {integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==} + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true @@ -3053,6 +3147,9 @@ packages: react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + react-remove-scroll-bar@2.3.6: resolution: {integrity: sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==} engines: {node: '>=10'} @@ -3093,6 +3190,12 @@ packages: '@types/react': optional: true + react-smooth@4.0.1: + resolution: {integrity: sha512-OE4hm7XqR0jNOq3Qmk9mFLyd6p2+j6bvbPJ7qlB7+oo0eNcL2l7WQzG6MBnT3EXY6xzkLMUBec3AfewJdA0J8w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-style-singleton@2.2.1: resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} engines: {node: '>=10'} @@ -3103,6 +3206,12 @@ packages: '@types/react': optional: true + react-transition-group@4.4.5: + resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} + peerDependencies: + react: '>=16.6.0' + react-dom: '>=16.6.0' + react@18.3.1: resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} @@ -3114,6 +3223,16 @@ packages: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} + recharts-scale@0.4.5: + resolution: {integrity: sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==} + + recharts@2.13.3: + resolution: {integrity: sha512-YDZ9dOfK9t3ycwxgKbrnDlRC4BHdjlY73fet3a0C1+qGMjXVZe6+VXmpOIIhzkje5MMEL8AN4hLIe4AMskBzlA==} + engines: {node: '>=14'} + peerDependencies: + react: ^16.0.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 + reflect.getprototypeof@1.0.6: resolution: {integrity: sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==} engines: {node: '>= 0.4'} @@ -3340,6 +3459,9 @@ packages: resolution: {integrity: sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww==} engines: {node: '>=0.12'} + tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -3451,6 +3573,9 @@ packages: react: ^16.8 || ^17.0 || ^18.0 react-dom: ^16.8 || ^17.0 || ^18.0 + victory-vendor@36.9.2: + resolution: {integrity: sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==} + which-boxed-primitive@1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} @@ -4582,6 +4707,30 @@ snapshots: '@types/cookie@0.6.0': {} + '@types/d3-array@3.2.1': {} + + '@types/d3-color@3.1.3': {} + + '@types/d3-ease@3.0.2': {} + + '@types/d3-interpolate@3.0.4': + dependencies: + '@types/d3-color': 3.1.3 + + '@types/d3-path@3.1.0': {} + + '@types/d3-scale@4.0.8': + dependencies: + '@types/d3-time': 3.0.4 + + '@types/d3-shape@3.1.6': + dependencies: + '@types/d3-path': 3.1.0 + + '@types/d3-time@3.0.4': {} + + '@types/d3-timer@3.0.2': {} + '@types/eslint@8.56.11': dependencies: '@types/estree': 1.0.5 @@ -4975,6 +5124,44 @@ snapshots: csstype@3.1.3: {} + d3-array@3.2.4: + dependencies: + internmap: 2.0.3 + + d3-color@3.1.0: {} + + d3-ease@3.0.1: {} + + d3-format@3.1.0: {} + + d3-interpolate@3.0.1: + dependencies: + d3-color: 3.1.0 + + d3-path@3.1.0: {} + + d3-scale@4.0.2: + dependencies: + d3-array: 3.2.4 + d3-format: 3.1.0 + d3-interpolate: 3.0.1 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + + d3-shape@3.2.0: + dependencies: + d3-path: 3.1.0 + + d3-time-format@4.1.0: + dependencies: + d3-time: 3.1.0 + + d3-time@3.1.0: + dependencies: + d3-array: 3.2.4 + + d3-timer@3.0.1: {} + d@1.0.2: dependencies: es5-ext: 0.10.64 @@ -5010,6 +5197,8 @@ snapshots: dependencies: ms: 2.1.2 + decimal.js-light@2.5.1: {} + deep-equal@2.2.3: dependencies: array-buffer-byte-length: 1.0.1 @@ -5069,6 +5258,11 @@ snapshots: dependencies: esutils: 2.0.3 + dom-helpers@5.2.1: + dependencies: + '@babel/runtime': 7.25.6 + csstype: 3.1.3 + dotenv@16.4.5: {} dreamopt@0.8.0: @@ -5550,12 +5744,16 @@ snapshots: d: 1.0.2 es5-ext: 0.10.64 + eventemitter3@4.0.7: {} + ext@1.7.0: dependencies: type: 2.7.3 fast-deep-equal@3.1.3: {} + fast-equals@5.0.1: {} + fast-glob@3.3.2: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -5759,6 +5957,8 @@ snapshots: hasown: 2.0.2 side-channel: 1.0.6 + internmap@2.0.3: {} + invariant@2.2.4: dependencies: loose-envify: 1.4.0 @@ -5992,6 +6192,8 @@ snapshots: lodash.throttle@4.1.1: {} + lodash@4.17.21: {} + loose-envify@1.4.0: dependencies: js-tokens: 4.0.0 @@ -6345,6 +6547,8 @@ snapshots: react-is@16.13.1: {} + react-is@18.3.1: {} + react-remove-scroll-bar@2.3.6(@types/react@18.3.3)(react@18.3.1): dependencies: react: 18.3.1 @@ -6386,6 +6590,14 @@ snapshots: optionalDependencies: '@types/react': 18.3.3 + react-smooth@4.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + fast-equals: 5.0.1 + prop-types: 15.8.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-transition-group: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-style-singleton@2.2.1(@types/react@18.3.3)(react@18.3.1): dependencies: get-nonce: 1.0.1 @@ -6395,6 +6607,15 @@ snapshots: optionalDependencies: '@types/react': 18.3.3 + react-transition-group@4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.25.6 + dom-helpers: 5.2.1 + loose-envify: 1.4.0 + prop-types: 15.8.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react@18.3.1: dependencies: loose-envify: 1.4.0 @@ -6407,6 +6628,23 @@ snapshots: dependencies: picomatch: 2.3.1 + recharts-scale@0.4.5: + dependencies: + decimal.js-light: 2.5.1 + + recharts@2.13.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + clsx: 2.1.1 + eventemitter3: 4.0.7 + lodash: 4.17.21 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-is: 18.3.1 + react-smooth: 4.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + recharts-scale: 0.4.5 + tiny-invariant: 1.3.3 + victory-vendor: 36.9.2 + reflect.getprototypeof@1.0.6: dependencies: call-bind: 1.0.7 @@ -6674,6 +6912,8 @@ snapshots: es5-ext: 0.10.64 next-tick: 1.1.0 + tiny-invariant@1.3.3: {} + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 @@ -6801,6 +7041,23 @@ snapshots: - '@types/react' - '@types/react-dom' + victory-vendor@36.9.2: + dependencies: + '@types/d3-array': 3.2.1 + '@types/d3-ease': 3.0.2 + '@types/d3-interpolate': 3.0.4 + '@types/d3-scale': 4.0.8 + '@types/d3-shape': 3.1.6 + '@types/d3-time': 3.0.4 + '@types/d3-timer': 3.0.2 + d3-array: 3.2.4 + d3-ease: 3.0.1 + d3-interpolate: 3.0.1 + d3-scale: 4.0.2 + d3-shape: 3.2.0 + d3-time: 3.1.0 + d3-timer: 3.0.1 + which-boxed-primitive@1.0.2: dependencies: is-bigint: 1.0.4 diff --git a/src/app/account/billtracker/page.tsx b/src/app/account/billtracker/page.tsx old mode 100755 new mode 100644 index f22f4df..c31bdd6 --- a/src/app/account/billtracker/page.tsx +++ b/src/app/account/billtracker/page.tsx @@ -1,19 +1,148 @@ -"use server" -import { auth } from "~/auth" -import BreadCrumbBillTracker from "~/components/portal/home/breadcrumb/BreadCrumbBillTracker" -import BillTrackerCalendar from "~/components/portal/billtracker/BillTrackerCalendar" +'use client' -export default async function HomePage() { - const session = await auth() - if (!session?.user) return <> - return ( -
-
-
- -
-
- < BillTrackerCalendar /> +import { useState } from 'react' +import { Button } from "~/components/ui/button" +import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card" +import { Calendar } from "~/components/ui/calendar" +import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "~/components/ui/dialog" +import { Input } from "~/components/ui/input" +import { Label } from "~/components/ui/label" +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "~/components/ui/select" +import { Plus, DollarSign } from 'lucide-react' + +// Mock data for bills +const initialBills = [ + { id: 1, name: 'Electricity', amount: 80, dueDate: new Date(2023, 6, 15), category: 'Utilities' }, + { id: 2, name: 'Internet', amount: 60, dueDate: new Date(2023, 6, 20), category: 'Utilities' }, + { id: 3, name: 'Water', amount: 40, dueDate: new Date(2023, 6, 25), category: 'Utilities' }, +] + +export default function BillTrackerPage() { + const [bills, setBills] = useState(initialBills) + const [selectedDate, setSelectedDate] = useState(new Date()) + const [isDialogOpen, setIsDialogOpen] = useState(false) + + const handleAddBill = (event: React.FormEvent) => { + event.preventDefault() + const formData = new FormData(event.currentTarget) + const newBill = { + id: bills.length + 1, + name: formData.get('billName') as string, + amount: Number(formData.get('amount')), + dueDate: selectedDate as Date, + category: formData.get('category') as string, + } + setBills([...bills, newBill]) + setIsDialogOpen(false) + } + + const getDayContent = (day: Date | undefined) => { + if (!day) return null; + const dayBills = bills.filter(bill => + bill.dueDate.getDate() === day.getDate() && + bill.dueDate.getMonth() === day.getMonth() && + bill.dueDate.getFullYear() === day.getFullYear() + ) + return dayBills.length > 0 ? ( +
+
- ); + ) : null + } + + return ( +
+ + +
+ Bill Tracker + + + + + +
+ + Add New Bill + + Enter the details of the bill you want to track. + + +
+
+ + +
+
+ + +
+
+ + +
+
+ + + +
+
+
+
+
+ +
+
+ getDayContent(date), + }} + /> +
+
+

Upcoming Bills

+
    + {bills.map((bill) => ( +
  • +
    +

    {bill.name}

    +

    {bill.dueDate.toLocaleDateString()}

    +
    +
    + + {bill.amount.toFixed(2)} +
    +
  • + ))} +
+
+
+
+
+
+ ) } + diff --git a/src/app/account/billtracker/page.tsx.bak b/src/app/account/billtracker/page.tsx.bak new file mode 100755 index 0000000..f22f4df --- /dev/null +++ b/src/app/account/billtracker/page.tsx.bak @@ -0,0 +1,19 @@ +"use server" +import { auth } from "~/auth" +import BreadCrumbBillTracker from "~/components/portal/home/breadcrumb/BreadCrumbBillTracker" +import BillTrackerCalendar from "~/components/portal/billtracker/BillTrackerCalendar" + +export default async function HomePage() { + const session = await auth() + if (!session?.user) return <> + return ( +
+
+
+ +
+
+ < BillTrackerCalendar /> +
+ ); +} diff --git a/src/app/account/documents/page.tsx b/src/app/account/documents/page.tsx index e69de29..d56e85e 100644 --- a/src/app/account/documents/page.tsx +++ b/src/app/account/documents/page.tsx @@ -0,0 +1,63 @@ +import { Button } from "~/components/ui/button" +import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card" +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "~/components/ui/table" +import { FileText, Download, Upload } from 'lucide-react' + +// Mock data for documents +const documents = [ + { id: 1, name: 'Lease Agreement', type: 'PDF', size: '2.5 MB', date: '2023-01-15' }, + { id: 2, name: 'Move-in Checklist', type: 'DOCX', size: '1.2 MB', date: '2023-01-15' }, + { id: 3, name: 'Rent Payment Receipt - June 2023', type: 'PDF', size: '0.5 MB', date: '2023-06-01' }, + { id: 4, name: 'Property Rules and Regulations', type: 'PDF', size: '1.8 MB', date: '2023-01-15' }, +] + +export default function DocumentsPage() { + return ( +
+ + +
+ Documents + +
+
+ + + + + Name + Type + Size + Date + Action + + + + {documents.map((doc) => ( + + +
+ + {doc.name} +
+
+ {doc.type} + {doc.size} + {doc.date} + + + +
+ ))} +
+
+
+
+
+ ) +} + diff --git a/src/app/account/messages/page.tsx b/src/app/account/messages/page.tsx index e69de29..de40d15 100644 --- a/src/app/account/messages/page.tsx +++ b/src/app/account/messages/page.tsx @@ -0,0 +1,70 @@ +'use client' + +import { useState } from 'react' +import { Button } from "~/components/ui/button" +import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card" +import { Input } from "~/components/ui/input" +import { Avatar, AvatarFallback } from "~/components/ui/avatar" + +// Mock data for messages +const initialMessages = [ + { id: 1, sender: 'Property Manager', content: 'Your maintenance request has been received and scheduled for next Tuesday.', timestamp: '2023-06-20T10:30:00Z' }, + { id: 2, sender: 'Tenant', content: 'Thank you for the quick response. I'll make sure to be available on Tuesday.', timestamp: '2023-06-20T11:15:00Z' }, + { id: 3, sender: 'Property Manager', content: 'Great! The maintenance team will arrive between 9 AM and 12 PM. Please ensure they have access to the affected area.', timestamp: '2023-06-20T14:00:00Z' }, +] + +export default function MessagesPage() { + const [messages, setMessages] = useState(initialMessages) + const [newMessage, setNewMessage] = useState('') + + const handleSendMessage = (e: React.FormEvent) => { + e.preventDefault() + if (newMessage.trim()) { + const message = { + id: messages.length + 1, + sender: 'Tenant', + content: newMessage, + timestamp: new Date().toISOString(), + } + setMessages([...messages, message]) + setNewMessage('') + } + } + + return ( +
+ + + Messages + + +
+ {messages.map((message) => ( +
+
+ + {message.sender[0]} + +
+

{message.sender}

+

{message.content}

+

{new Date(message.timestamp).toLocaleString()}

+
+
+
+ ))} +
+
+ setNewMessage(e.target.value)} + placeholder="Type your message..." + className="flex-grow" + /> + +
+
+
+
+ ) +} diff --git a/src/app/account/payments/page.tsx b/src/app/account/payments/page.tsx index e69de29..14ec53f 100644 --- a/src/app/account/payments/page.tsx +++ b/src/app/account/payments/page.tsx @@ -0,0 +1,80 @@ +import { Button } from "~/components/ui/button" +import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "~/components/ui/card" +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "~/components/ui/table" +import { CreditCard, DollarSign } from 'lucide-react' + +// This would typically come from your database +const paymentHistory = [ + { id: 1, date: '2023-06-01', amount: 1200, status: 'Paid' }, + { id: 2, date: '2023-05-01', amount: 1200, status: 'Paid' }, + { id: 3, date: '2023-04-01', amount: 1200, status: 'Paid' }, +] + +export default function PaymentsPage() { + return ( +
+ + + Current Balance + + +
$1,200.00
+

Due on July 1, 2023

+
+ + + +
+ + + + Payment Methods + Manage your payment methods + + +
+
+ +
+

Visa ending in 1234

+

Expires 12/2025

+
+
+ +
+
+ + + +
+ + + + Payment History + + + + + + Date + Amount + Status + + + + {paymentHistory.map((payment) => ( + + {payment.date} + ${payment.amount.toFixed(2)} + {payment.status} + + ))} + +
+
+
+
+ ) +} diff --git a/src/app/account/workorders/page.tsx b/src/app/account/workorders/page.tsx index e69de29..cb65c53 100644 --- a/src/app/account/workorders/page.tsx +++ b/src/app/account/workorders/page.tsx @@ -0,0 +1,135 @@ +'use client' + +import { useState } from 'react' +import { Button } from "~/components/ui/button" +import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "~/components/ui/card" +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "~/components/ui/table" +import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "~/components/ui/dialog" +import { Input } from "~/components/ui/input" +import { Label } from "~/components/ui/label" +import { Textarea } from "~/components/ui/textarea" +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "~/components/ui/select" +import { PenToolIcon as Tool, Plus } from 'lucide-react' + +// This would typically come from your database +const workOrders = [ + { id: 1, date: '2023-06-15', issue: 'Leaky faucet', status: 'In Progress' }, + { id: 2, date: '2023-06-10', issue: 'Broken AC', status: 'Scheduled' }, + { id: 3, date: '2023-05-28', issue: 'Clogged drain', status: 'Completed' }, +] + +export default function WorkOrdersPage() { + const [isDialogOpen, setIsDialogOpen] = useState(false) + + const handleSubmit = (event: React.FormEvent) => { + event.preventDefault() + // Here you would typically send the form data to your server + setIsDialogOpen(false) + } + + return ( +
+ + +
+ Work Orders + + + + + +
+ + Create New Work Order + + Describe the issue you're experiencing. We'll get on it as soon as possible. + + +
+
+ + +
+
+ + +
+
+ +