diff --git a/.env.example b/.env.example deleted file mode 100755 index 72980c2..0000000 --- a/.env.example +++ /dev/null @@ -1,17 +0,0 @@ -# When adding additional environment variables, the schema in "/src/env.js" -# should be updated accordingly. - -# Examples: -# SERVERVAR="foo" -# NEXT_PUBLIC_CLIENTVAR="bar" - -# Drizzle -## WAN -DATABASE_URL="postgresql://postgres:password@localhost:5432/example_db" -## LAN -DATABASE_URL="postgresql://postgres:password@localhost:5432/example_db" - -# Auth.js -# openssl rand -base64 33 -AUTH_SECRET="" -# Auth.js Providers: diff --git a/package.json b/package.json index 7f77556..3260796 100755 --- a/package.json +++ b/package.json @@ -27,7 +27,11 @@ "@radix-ui/react-label": "^2.1.0", "@radix-ui/react-navigation-menu": "^1.2.0", "@radix-ui/react-popover": "^1.1.1", + "@radix-ui/react-progress": "^1.1.0", + "@radix-ui/react-select": "^2.1.2", + "@radix-ui/react-slider": "^1.2.1", "@radix-ui/react-slot": "^1.1.0", + "@radix-ui/react-tabs": "^1.1.1", "@radix-ui/react-toast": "^1.2.1", "@t3-oss/env-nextjs": "^0.10.1", "@types/jsonwebtoken": "^9.0.6", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6af0860..136cfe0 100755 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -38,9 +38,21 @@ importers: '@radix-ui/react-popover': specifier: ^1.1.1 version: 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-progress': + specifier: ^1.1.0 + version: 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-select': + specifier: ^2.1.2 + version: 2.1.2(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slider': + specifier: ^1.2.1 + version: 1.2.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-slot': specifier: ^1.1.0 version: 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-tabs': + specifier: ^1.1.1 + version: 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-toast': specifier: ^1.2.1 version: 1.2.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -778,6 +790,9 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} + '@radix-ui/number@1.1.0': + resolution: {integrity: sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==} + '@radix-ui/primitive@1.0.1': resolution: {integrity: sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==} @@ -885,6 +900,15 @@ packages: '@types/react': optional: true + '@radix-ui/react-context@1.1.1': + resolution: {integrity: sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@radix-ui/react-dialog@1.0.5': resolution: {integrity: sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==} peerDependencies: @@ -946,6 +970,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-dismissable-layer@1.1.1': + resolution: {integrity: sha512-QSxg29lfr/xcev6kSz7MAlmDnzbP1eI/Dwn3Tp1ip0KT5CUELsxkekFEMVBEoykI3oV39hKT4TKZzBNMbcTZYQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-dropdown-menu@2.1.1': resolution: {integrity: sha512-y8E+x9fBq9qvteD2Zwa4397pUVhYsh9iq44b5RD5qu1GMJWBCBuVg1hMyItbc6+zH00TxGRqd9Iot4wzf3OoBQ==} peerDependencies: @@ -977,6 +1014,15 @@ packages: '@types/react': optional: true + '@radix-ui/react-focus-guards@1.1.1': + resolution: {integrity: sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@radix-ui/react-focus-scope@1.0.4': resolution: {integrity: sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==} peerDependencies: @@ -1112,6 +1158,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-portal@1.1.2': + resolution: {integrity: sha512-WeDYLGPxJb/5EGBoedyJbT0MpoULmwnIPMJMSldkuiMsBAv7N1cRdsTWZWht9vpPOiN3qyiGAtbK2is47/uMFg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-presence@1.0.1': resolution: {integrity: sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==} peerDependencies: @@ -1138,6 +1197,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-presence@1.1.1': + resolution: {integrity: sha512-IeFXVi4YS1K0wVZzXNrbaaUvIJ3qdY+/Ih4eHFhWA9SwGR9UDX7Ck8abvL57C4cv3wwMvUE0OG69Qc3NCcTe/A==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-primitive@1.0.3': resolution: {integrity: sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==} peerDependencies: @@ -1164,6 +1236,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-progress@1.1.0': + resolution: {integrity: sha512-aSzvnYpP725CROcxAOEBVZZSIQVQdHgBr2QQFKySsaD14u8dNT0batuXI+AAGDdAHfXH8rbnHmjYFqVJ21KkRg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-roving-focus@1.1.0': resolution: {integrity: sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==} peerDependencies: @@ -1177,6 +1262,32 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-select@2.1.2': + resolution: {integrity: sha512-rZJtWmorC7dFRi0owDmoijm6nSJH1tVw64QGiNIZ9PNLyBDtG+iAq+XGsya052At4BfarzY/Dhv9wrrUr6IMZA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-slider@1.2.1': + resolution: {integrity: sha512-bEzQoDW0XP+h/oGbutF5VMWJPAl/UU8IJjr7h02SOHDIIIxq+cep8nItVNoBV+OMmahCdqdF38FTpmXoqQUGvw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-slot@1.0.2': resolution: {integrity: sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==} peerDependencies: @@ -1195,6 +1306,19 @@ packages: '@types/react': optional: true + '@radix-ui/react-tabs@1.1.1': + resolution: {integrity: sha512-3GBUDmP2DvzmtYLMsHmpA1GtR46ZDZ+OreXM/N+kkQJOPIgytFWWTfDQmBQKBvaFS0Vno0FktdbVzN28KGrMdw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-toast@1.2.1': resolution: {integrity: sha512-5trl7piMXcZiCq7MW6r8YYmu0bK5qDpTWz+FdEPdKyft2UixkspheYbjbrLXVN5NGKHFbOP7lm8eD0biiSqZqg==} peerDependencies: @@ -2959,6 +3083,16 @@ packages: '@types/react': optional: true + react-remove-scroll@2.6.0: + resolution: {integrity: sha512-I2U4JVEsQenxDAKaVa3VZ/JeJZe0/2DxPWL8Tj8yLKctQJQiZM52pn/GWFpSp8dftjM3pSAHVJZscAnC/y+ySQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + react-style-singleton@2.2.1: resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} engines: {node: '>=10'} @@ -3759,6 +3893,8 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true + '@radix-ui/number@1.1.0': {} + '@radix-ui/primitive@1.0.1': dependencies: '@babel/runtime': 7.25.6 @@ -3854,6 +3990,12 @@ snapshots: optionalDependencies: '@types/react': 18.3.3 + '@radix-ui/react-context@1.1.1(@types/react@18.3.3)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.3 + '@radix-ui/react-dialog@1.0.5(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.25.6 @@ -3932,6 +4074,19 @@ snapshots: '@types/react': 18.3.3 '@types/react-dom': 18.3.0 + '@radix-ui/react-dismissable-layer@1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-use-escape-keydown': 1.1.0(@types/react@18.3.3)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + '@radix-ui/react-dropdown-menu@2.1.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.0 @@ -3960,6 +4115,12 @@ snapshots: optionalDependencies: '@types/react': 18.3.3 + '@radix-ui/react-focus-guards@1.1.1(@types/react@18.3.3)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.3 + '@radix-ui/react-focus-scope@1.0.4(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.25.6 @@ -4116,6 +4277,16 @@ snapshots: '@types/react': 18.3.3 '@types/react-dom': 18.3.0 + '@radix-ui/react-portal@1.1.2(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.3)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + '@radix-ui/react-presence@1.0.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.25.6 @@ -4137,6 +4308,16 @@ snapshots: '@types/react': 18.3.3 '@types/react-dom': 18.3.0 + '@radix-ui/react-presence@1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.3)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + '@radix-ui/react-primitive@1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.25.6 @@ -4156,6 +4337,16 @@ snapshots: '@types/react': 18.3.3 '@types/react-dom': 18.3.0 + '@radix-ui/react-progress@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-context': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + '@radix-ui/react-roving-focus@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.0 @@ -4173,6 +4364,54 @@ snapshots: '@types/react': 18.3.3 '@types/react-dom': 18.3.0 + '@radix-ui/react-select@2.1.2(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/number': 1.1.0 + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-collection': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-popper': 1.2.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.2(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + aria-hidden: 1.2.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.6.0(@types/react@18.3.3)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-slider@1.2.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/number': 1.1.0 + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-collection': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.3)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + '@radix-ui/react-slot@1.0.2(@types/react@18.3.3)(react@18.3.1)': dependencies: '@babel/runtime': 7.25.6 @@ -4188,6 +4427,22 @@ snapshots: optionalDependencies: '@types/react': 18.3.3 + '@radix-ui/react-tabs@1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-context': 1.1.1(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-presence': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.3)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + '@radix-ui/react-toast@1.2.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.0 @@ -5105,7 +5360,7 @@ snapshots: debug: 4.3.6 enhanced-resolve: 5.17.1 eslint: 8.57.0 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0) fast-glob: 3.3.2 get-tsconfig: 4.7.6 @@ -5127,7 +5382,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0): + eslint-module-utils@2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): dependencies: debug: 3.2.7 optionalDependencies: @@ -6120,6 +6375,17 @@ snapshots: optionalDependencies: '@types/react': 18.3.3 + react-remove-scroll@2.6.0(@types/react@18.3.3)(react@18.3.1): + dependencies: + react: 18.3.1 + react-remove-scroll-bar: 2.3.6(@types/react@18.3.3)(react@18.3.1) + react-style-singleton: 2.2.1(@types/react@18.3.3)(react@18.3.1) + tslib: 2.6.3 + use-callback-ref: 1.3.2(@types/react@18.3.3)(react@18.3.1) + use-sidecar: 1.1.2(@types/react@18.3.3)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.3 + react-style-singleton@2.2.1(@types/react@18.3.3)(react@18.3.1): dependencies: get-nonce: 1.0.1 diff --git a/src/app/billtracker/page.tsx b/src/app/account/billtracker/page.tsx similarity index 69% rename from src/app/billtracker/page.tsx rename to src/app/account/billtracker/page.tsx index 9de7a79..f22f4df 100755 --- a/src/app/billtracker/page.tsx +++ b/src/app/account/billtracker/page.tsx @@ -1,7 +1,7 @@ "use server" import { auth } from "~/auth" -import BreadCrumbBillTracker from "~/components/home/breadcrumb/BreadCrumbBillTracker" -import BillTrackerCalendar from "~/components/billtracker/BillTrackerCalendar" +import BreadCrumbBillTracker from "~/components/portal/home/breadcrumb/BreadCrumbBillTracker" +import BillTrackerCalendar from "~/components/portal/billtracker/BillTrackerCalendar" export default async function HomePage() { const session = await auth() diff --git a/src/app/account/documents/page.tsx b/src/app/account/documents/page.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/app/account/layout.tsx b/src/app/account/layout.tsx new file mode 100644 index 0000000..b19634b --- /dev/null +++ b/src/app/account/layout.tsx @@ -0,0 +1,59 @@ +import Link from 'next/link' +import { Button } from "~/components/ui/button" +import { Card, CardContent } from "~/components/ui/card" +import { CreditCard, FileText, MessageSquare, PenToolIcon as Tool, BarChart } from 'lucide-react' + +export default function AccountLayout({ + children, +}: { + children: React.ReactNode +}) { + return ( +
+

My Account

+
+ + + + + +
+ {children} +
+
+
+ ) +} + + diff --git a/src/app/account/messages/page.tsx b/src/app/account/messages/page.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/app/account/page.tsx b/src/app/account/page.tsx new file mode 100644 index 0000000..07511a6 --- /dev/null +++ b/src/app/account/page.tsx @@ -0,0 +1,112 @@ +import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card" +import { Button } from "~/components/ui/button" +import { Progress } from "~/components/ui/progress" +import { CreditCard, AlertTriangle, CheckCircle } from 'lucide-react' + +export default function AccountHomePage() { + // This data would typically come from your backend + const accountData = { + balance: 1200, + nextPaymentDue: "2023-07-01", + recentPayment: { + amount: 1200, + date: "2023-06-01" + }, + workOrders: [ + { id: 1, title: "Leaky faucet", status: "In Progress" }, + { id: 2, title: "Broken AC", status: "Scheduled" } + ], + documents: [ + { id: 1, title: "Lease Agreement", date: "2023-01-15" }, + { id: 2, title: "Move-in Checklist", date: "2023-01-15" } + ] + } + + return ( +
+ + + Account Overview + + +
+ + + Current Balance + + + +
${accountData.balance}
+

+ Next payment due: {accountData.nextPaymentDue} +

+
+
+ + + Recent Payment + + + +
${accountData.recentPayment.amount}
+

+ Paid on: {accountData.recentPayment.date} +

+
+
+ + + Lease Progress + + + + +

+ 4 months remaining +

+
+
+
+
+
+ +
+ + + Recent Work Orders + + +
    + {accountData.workOrders.map(order => ( +
  • + {order.title} + {order.status} +
  • + ))} +
+ +
+
+ + + + Recent Documents + + +
    + {accountData.documents.map(doc => ( +
  • + {doc.title} + {doc.date} +
  • + ))} +
+ +
+
+
+
+ ) +} + + diff --git a/src/app/account/payments/page.tsx b/src/app/account/payments/page.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/app/account/workorders/page.tsx b/src/app/account/workorders/page.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/app/contact/page.tsx b/src/app/contact/page.tsx new file mode 100644 index 0000000..265849e --- /dev/null +++ b/src/app/contact/page.tsx @@ -0,0 +1,83 @@ +import type { Metadata } from 'next' +import ContactForm from '~/components/contact/contact-form' +import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card" +import { MapPin, Phone, Mail, Clock } from 'lucide-react' + +export const metadata: Metadata = { + title: 'Contact Us | PropertyPro', + description: 'Get in touch with PropertyPro for any inquiries about our properties or services.', +} + +export default function ContactPage() { + return ( +
+

Contact Us

+ +
+
+ +
+ +
+ + + Our Office + + +

+ + 123 Property Street, Cityville, State 12345 +

+

+ + (123) 456-7890 +

+

+ + info@propertypro.com +

+

+ + Mon-Fri: 9am-5pm, Sat: 10am-3pm, Sun: Closed +

+
+
+ + + + FAQ + + +
+

How do I schedule a property viewing?

+

You can schedule a viewing by contacting our office or using the form on this page.

+
+
+

What documents do I need to apply for a rental?

+

Typically, you'll need proof of income, identification, and references. Specific requirements may vary.

+
+
+

How do I report maintenance issues?

+

Tenants can report maintenance issues through their online account or by contacting our office directly.

+
+
+
+ +
+ +
+
+
+
+ ) +} + diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 031692c..1ee0adf 100755 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -8,6 +8,7 @@ import { type Metadata } from "next"; import Theme_Toggle from '~/components/theme/theme_toggle' import { Button } from "~/components/ui/button" import Link from 'next/link' +import Avatar_Popover from "~/components/auth/AvatarPopover"; export const metadata: Metadata = { title: "Tenant Portal", @@ -25,8 +26,76 @@ export default async function RootLayout({ }: Readonly<{ children: React.ReactNode }>) { const session = await auth(); if (!session?.user) { - } - return ( + return ( + + + + +
+
+
+ Magnolia Coast Properties + +
+ + + + +
+
+
+ {children} + +
+
+
+ + + ); + } else { + return (
- Magnolia Coast Properties + Magnolia Coast Properties -
+
- - +
@@ -70,11 +138,11 @@ export default async function RootLayout({

Quick Links

@@ -95,5 +163,6 @@ export default async function RootLayout({ - ); + ); + } } diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx new file mode 100644 index 0000000..f81ad6d --- /dev/null +++ b/src/app/login/page.tsx @@ -0,0 +1,127 @@ +'use client' + +import { useState } from 'react' +import { Button } from "~/components/ui/button" +import { Input } from "~/components/ui/input" +import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "~/components/ui/card" +import { Tabs, TabsContent, TabsList, TabsTrigger } from "~/components/ui/tabs" +import { Label } from "~/components/ui/label" +import { Eye, EyeOff } from 'lucide-react' +import Sign_In from "~/components/auth/client/SignInAppleButton" + +export default function AuthPage() { + const [showPassword, setShowPassword] = useState(false) + + const togglePasswordVisibility = () => setShowPassword(!showPassword) + + return ( +
+ + + + Welcome to Magnolia Coast Property Management + + + Login or create an account to get started + + + + + + Login + Register + + +
+
+
+ + +
+
+ +
+ + +
+
+
+
+ + +
+
+
+ +
+
+
+ + +
+
+ + +
+
+ +
+ + +
+
+
+
+ + +
+
+
+
+
+ +

+ By continuing, you agree to our{' '} + Terms of Service and{' '} + Privacy Policy +

+
+
+
+ ); +} + diff --git a/src/app/page.tsx b/src/app/page.tsx index 007a5da..7c6071e 100755 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -34,7 +34,9 @@ export default async function HomePage() {

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

- + + + ))} diff --git a/src/app/properties/[id]/page.tsx b/src/app/properties/[id]/page.tsx new file mode 100644 index 0000000..50dd4c5 --- /dev/null +++ b/src/app/properties/[id]/page.tsx @@ -0,0 +1,86 @@ +import Link from 'next/link' +import { Button } from "~/components/ui/button" +import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card" +import { Home, Bed, Bath, Square, MapPin, Calendar, DollarSign } from 'lucide-react' + +// This would typically come from your database +const property = { + id: 1, + title: "Luxurious Family Home", + type: "House", + bedrooms: 4, + bathrooms: 3, + area: 2500, + price: 750000, + address: "123 Main St, Anytown, USA", + description: "This beautiful family home features spacious living areas, a modern kitchen, and a large backyard perfect for entertaining. Located in a quiet neighborhood with easy access to schools and shopping.", + amenities: ["Central Air", "Garage", "Fireplace", "Hardwood Floors", "Swimming Pool"], + yearBuilt: 2015, +} + +export default function PropertyPage({ params }: { params: { id: string } }) { + return ( +
+ + ← Back to Properties + + +
+
+ {property.title} +
+ Additional view 1 + Additional view 2 +
+
+ +
+

{property.title}

+

${property.price.toLocaleString()}

+ +
+
+ {property.type} +
+
+ {property.bedrooms} Bedrooms +
+
+ {property.bathrooms} Bathrooms +
+
+ {property.area} sqft +
+
+ {property.address} +
+
+ Built in {property.yearBuilt} +
+
+ +

{property.description}

+ + + + Amenities + + +
    + {property.amenities.map((amenity, index) => ( +
  • + {amenity} +
  • + ))} +
+
+
+ + +
+
+
+ ) +} + + diff --git a/src/app/properties/page.tsx b/src/app/properties/page.tsx new file mode 100644 index 0000000..3e7b54f --- /dev/null +++ b/src/app/properties/page.tsx @@ -0,0 +1,116 @@ +'use client' + +import { useState } from 'react' +import Link from 'next/link' +import { Button } from "~/components/ui/button" +import { Input } from "~/components/ui/input" +import { Card, CardContent, CardFooter, CardHeader, CardTitle } from "~/components/ui/card" +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "~/components/ui/select" +import { Slider } from "~/components/ui/slider" +import { Search, Home, Bed, Bath, Square } from 'lucide-react' + +// Mock data for properties +const properties = Array.from({ length: 12 }, (_, i) => ({ + id: i + 1, + title: `Property ${i + 1}`, + type: i % 3 === 0 ? 'House' : i % 3 === 1 ? 'Apartment' : 'Condo', + bedrooms: Math.floor(Math.random() * 5) + 1, + bathrooms: Math.floor(Math.random() * 3) + 1, + area: Math.floor(Math.random() * 1000) + 500, + price: Math.floor(Math.random() * 500000) + 100000, +})) + +export default function PropertiesPage() { + const [sortBy, setSortBy] = useState('price') + const [filterType, setFilterType] = useState('All') + const [priceRange, setPriceRange] = useState([0, 1000000]) + const [searchTerm, setSearchTerm] = useState('') + + const filteredAndSortedProperties = properties + .filter(property => + (filterType === 'All' || property.type === filterType) && + property.price >= priceRange[0] && property.price <= priceRange[1] && + property.title.toLowerCase().includes(searchTerm.toLowerCase()) + ) + .sort((a, b) => { + if (sortBy === 'price') return a.price - b.price + if (sortBy === 'bedrooms') return b.bedrooms - a.bedrooms + return 0 + }) + + return ( +
+

Available Properties

+ +
+ setSearchTerm(e.target.value)} + className="max-w-xs" + /> + + +
+ +
+

Price Range

+ +
+ ${priceRange[0].toLocaleString()} - ${priceRange[1].toLocaleString()} +
+
+ +
+ {filteredAndSortedProperties.map((property) => ( + + + {property.title} + + + {property.title} +
+ {property.type} + {property.bedrooms} + {property.bathrooms} + {property.area} sqft +
+

${property.price.toLocaleString()}

+
+ + + + + +
+ ))} +
+
+ ) +} + diff --git a/src/components/auth/No_Session.tsx b/src/components/auth/No_Session.tsx new file mode 100644 index 0000000..789e612 --- /dev/null +++ b/src/components/auth/No_Session.tsx @@ -0,0 +1,9 @@ +const No_Session = () => { + return ( +
+

Unauthorized Access

+

Please sign in to view this page.

+
+ ); +} +export default No_Session; diff --git a/src/components/auth/client/SignInAppleButton.tsx b/src/components/auth/client/SignInAppleButton.tsx index 817f6f7..161ea25 100755 --- a/src/components/auth/client/SignInAppleButton.tsx +++ b/src/components/auth/client/SignInAppleButton.tsx @@ -4,12 +4,12 @@ import Image from "next/image" export default function Sign_In() { return ( -
- Apple logo - -
+ ); } diff --git a/src/components/auth/client/SignOutButton.tsx b/src/components/auth/client/SignOutButton.tsx index ce3a8fc..75d014a 100755 --- a/src/components/auth/client/SignOutButton.tsx +++ b/src/components/auth/client/SignOutButton.tsx @@ -2,5 +2,13 @@ import { signOut } from "next-auth/react" import { Button } from "~/components/ui/button" export default function Sign_Out() { - return + return ( + + ); } diff --git a/src/components/auth/server/SignOutButton.tsx b/src/components/auth/server/SignOutButton.tsx index cdb410b..719fa03 100755 --- a/src/components/auth/server/SignOutButton.tsx +++ b/src/components/auth/server/SignOutButton.tsx @@ -1,3 +1,4 @@ +import { Button } from "~/components/ui/button" import { signOut } from "~/auth" export default function Sign_Out() { @@ -9,7 +10,10 @@ export default function Sign_Out() { await signOut() }} > - + ) } diff --git a/src/components/contact/contact-form.tsx b/src/components/contact/contact-form.tsx new file mode 100644 index 0000000..b172c1d --- /dev/null +++ b/src/components/contact/contact-form.tsx @@ -0,0 +1,82 @@ +'use client' + +import { useState } from 'react' +import { Button } from "~/components/ui/button" +import { Input } from "~/components/ui/input" +import { Textarea } from "~/components/ui/textarea" +import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "~/components/ui/card" +import { Label } from "~/components/ui/label" +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "~/components/ui/select" + +export default function ContactForm() { + const [formStatus, setFormStatus] = useState<'idle' | 'submitting' | 'success' | 'error'>('idle') + + const handleSubmit = async (event: React.FormEvent) => { + event.preventDefault() + setFormStatus('submitting') + + // Here you would typically send the form data to your server + // For this example, we'll just simulate a submission + setTimeout(() => { + setFormStatus('success') + }, 2000) + } + + return ( + + + Send us a message + We'll get back to you as soon as possible. + + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +