diff --git a/package.json b/package.json index 5c6eecc..c3aa97e 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,11 @@ }, "dependencies": { "@heroicons/react": "^2.1.3", + "@hookform/resolvers": "^3.3.4", "@radix-ui/react-context-menu": "^2.1.5", "@radix-ui/react-dialog": "^1.0.5", + "@radix-ui/react-label": "^2.0.2", + "@radix-ui/react-select": "^2.0.0", "@radix-ui/react-separator": "^1.0.3", "@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-toast": "^1.1.5", @@ -23,15 +26,17 @@ "lucide-react": "^0.368.0", "mcutils-library": "^1.2.1", "moment": "^2.30.1", - "next": "14.2.1", + "next": "14.2.2", "next-themes": "^0.3.0", "react": "^18", "react-countup": "^6.5.3", "react-dom": "^18", + "react-hook-form": "^7.51.3", "react-syntax-highlighter": "^15.5.0", "react-use-websocket": "3.0.0", "tailwind-merge": "^2.2.2", - "tailwindcss-animate": "^1.0.7" + "tailwindcss-animate": "^1.0.7", + "zod": "^3.22.4" }, "devDependencies": { "@types/node": "^20", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0ab101b..42ca846 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,12 +8,21 @@ dependencies: '@heroicons/react': specifier: ^2.1.3 version: 2.1.3(react@18.2.0) + '@hookform/resolvers': + specifier: ^3.3.4 + version: 3.3.4(react-hook-form@7.51.3) '@radix-ui/react-context-menu': specifier: ^2.1.5 version: 2.1.5(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-dialog': specifier: ^1.0.5 version: 1.0.5(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-label': + specifier: ^2.0.2 + version: 2.0.2(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-select': + specifier: ^2.0.0 + version: 2.0.0(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-separator': specifier: ^1.0.3 version: 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) @@ -48,8 +57,8 @@ dependencies: specifier: ^2.30.1 version: 2.30.1 next: - specifier: 14.2.1 - version: 14.2.1(@babel/core@7.24.4)(react-dom@18.2.0)(react@18.2.0) + specifier: 14.2.2 + version: 14.2.2(@babel/core@7.24.4)(react-dom@18.2.0)(react@18.2.0) next-themes: specifier: ^0.3.0 version: 0.3.0(react-dom@18.2.0)(react@18.2.0) @@ -62,6 +71,9 @@ dependencies: react-dom: specifier: ^18 version: 18.2.0(react@18.2.0) + react-hook-form: + specifier: ^7.51.3 + version: 7.51.3(react@18.2.0) react-syntax-highlighter: specifier: ^15.5.0 version: 15.5.0(react@18.2.0) @@ -74,6 +86,9 @@ dependencies: tailwindcss-animate: specifier: ^1.0.7 version: 1.0.7(tailwindcss@3.4.3) + zod: + specifier: ^3.22.4 + version: 3.22.4 devDependencies: '@types/node': @@ -539,6 +554,14 @@ packages: react: 18.2.0 dev: false + /@hookform/resolvers@3.3.4(react-hook-form@7.51.3): + resolution: {integrity: sha512-o5cgpGOuJYrd+iMKvkttOclgwRW86EsWJZZRC23prf0uU2i48Htq4PuT73AVb9ionFyZrwYEITuOFGF+BydEtQ==} + peerDependencies: + react-hook-form: ^7.0.0 + dependencies: + react-hook-form: 7.51.3(react@18.2.0) + dev: false + /@humanwhocodes/config-array@0.11.14: resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} @@ -832,8 +855,8 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: false - /@next/env@14.2.1: - resolution: {integrity: sha512-qsHJle3GU3CmVx7pUoXcghX4sRN+vINkbLdH611T8ZlsP//grzqVW87BSUgOZeSAD4q7ZdZicdwNe/20U2janA==} + /@next/env@14.2.2: + resolution: {integrity: sha512-sk72qRfM1Q90XZWYRoJKu/UWlTgihrASiYw/scb15u+tyzcze3bOuJ/UV6TBOQEeUaxOkRqGeuGUdiiuxc5oqw==} dev: false /@next/eslint-plugin-next@14.2.1: @@ -842,8 +865,8 @@ packages: glob: 10.3.10 dev: true - /@next/swc-darwin-arm64@14.2.1: - resolution: {integrity: sha512-kGjnjcIJehEcd3rT/3NAATJQndAEELk0J9GmGMXHSC75TMnvpOhONcjNHbjtcWE5HUQnIHy5JVkatrnYm1QhVw==} + /@next/swc-darwin-arm64@14.2.2: + resolution: {integrity: sha512-3iPgMhzbalizGwHNFUcGnDhFPSgVBHQ8aqSTAMxB5BvJG0oYrDf1WOJZlbXBgunOEj/8KMVbejEur/FpvFsgFQ==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] @@ -851,8 +874,8 @@ packages: dev: false optional: true - /@next/swc-darwin-x64@14.2.1: - resolution: {integrity: sha512-dAdWndgdQi7BK2WSXrx4lae7mYcOYjbHJUhvOUnJjMNYrmYhxbbvJ2xElZpxNxdfA6zkqagIB9He2tQk+l16ew==} + /@next/swc-darwin-x64@14.2.2: + resolution: {integrity: sha512-x7Afi/jt0ZBRUZHTi49yyej4o8znfIMHO4RvThuoc0P+uli8Jd99y5GKjxoYunPKsXL09xBXEM1+OQy2xEL0Ag==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] @@ -860,8 +883,8 @@ packages: dev: false optional: true - /@next/swc-linux-arm64-gnu@14.2.1: - resolution: {integrity: sha512-2ZctfnyFOGvTkoD6L+DtQtO3BfFz4CapoHnyLTXkOxbZkVRgg3TQBUjTD/xKrO1QWeydeo8AWfZRg8539qNKrg==} + /@next/swc-linux-arm64-gnu@14.2.2: + resolution: {integrity: sha512-zbfPtkk7L41ODMJwSp5VbmPozPmMMQrzAc0HAUomVeVIIwlDGs/UCqLJvLNDt4jpWgc21SjjyIn762lNGrMaUA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -869,8 +892,8 @@ packages: dev: false optional: true - /@next/swc-linux-arm64-musl@14.2.1: - resolution: {integrity: sha512-jazZXctiaanemy4r+TPIpFP36t1mMwWCKMsmrTRVChRqE6putyAxZA4PDujx0SnfvZHosjdkx9xIq9BzBB5tWg==} + /@next/swc-linux-arm64-musl@14.2.2: + resolution: {integrity: sha512-wPbS3pI/JU16rm3XdLvvTmlsmm1nd+sBa2ohXgBZcShX4TgOjD4R+RqHKlI1cjo/jDZKXt6OxmcU0Iys0OC/yg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -878,8 +901,8 @@ packages: dev: false optional: true - /@next/swc-linux-x64-gnu@14.2.1: - resolution: {integrity: sha512-VjCHWCjsAzQAAo8lkBOLEIkBZFdfW+Z18qcQ056kL4KpUYc8o59JhLDCBlhg+hINQRgzQ2UPGma2AURGOH0+Qg==} + /@next/swc-linux-x64-gnu@14.2.2: + resolution: {integrity: sha512-NqWOHqqq8iC9tuHvZxjQ2tX+jWy2X9y8NX2mcB4sj2bIccuCxbIZrU/ThFPZZPauygajZuVQ6zediejQHwZHwQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -887,8 +910,8 @@ packages: dev: false optional: true - /@next/swc-linux-x64-musl@14.2.1: - resolution: {integrity: sha512-7HZKYKvAp4nAHiHIbY04finRqjeYvkITOGOurP1aLMexIFG/1+oCnqhGogBdc4lao/lkMW1c+AkwWSzSlLasqw==} + /@next/swc-linux-x64-musl@14.2.2: + resolution: {integrity: sha512-lGepHhwb9sGhCcU7999+iK1ZZT+6rrIoVg40MP7DZski9GIZP80wORSbt5kJzh9v2x2ev2lxC6VgwMQT0PcgTA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -896,8 +919,8 @@ packages: dev: false optional: true - /@next/swc-win32-arm64-msvc@14.2.1: - resolution: {integrity: sha512-YGHklaJ/Cj/F0Xd8jxgj2p8po4JTCi6H7Z3Yics3xJhm9CPIqtl8erlpK1CLv+HInDqEWfXilqatF8YsLxxA2Q==} + /@next/swc-win32-arm64-msvc@14.2.2: + resolution: {integrity: sha512-TZSh/48SfcLEQ4rD25VVn2kdIgUWmMflRX3OiyPwGNXn3NiyPqhqei/BaqCYXViIQ+6QsG9R0C8LftMqy8JPMA==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] @@ -905,8 +928,8 @@ packages: dev: false optional: true - /@next/swc-win32-ia32-msvc@14.2.1: - resolution: {integrity: sha512-o+ISKOlvU/L43ZhtAAfCjwIfcwuZstiHVXq/BDsZwGqQE0h/81td95MPHliWCnFoikzWcYqh+hz54ZB2FIT8RA==} + /@next/swc-win32-ia32-msvc@14.2.2: + resolution: {integrity: sha512-M0tBVNMEBJN2ZNQWlcekMn6pvLria7Sa2Fai5znm7CCJz4pP3lrvlSxhKdkCerk0D9E0bqx5yAo3o2Q7RrD4gA==} engines: {node: '>= 10'} cpu: [ia32] os: [win32] @@ -914,8 +937,8 @@ packages: dev: false optional: true - /@next/swc-win32-x64-msvc@14.2.1: - resolution: {integrity: sha512-GmRoTiLcvCLifujlisknv4zu9/C4i9r0ktsA8E51EMqJL4bD4CpO7lDYr7SrUxCR0tS4RVcrqKmCak24T0ohaw==} + /@next/swc-win32-x64-msvc@14.2.2: + resolution: {integrity: sha512-a/20E/wtTJZ3Ykv3f/8F0l7TtgQa2LWHU2oNB9bsu0VjqGuGGHmm/q6waoUNQYTVPYrrlxxaHjJcDV6aiSTt/w==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -947,6 +970,12 @@ packages: requiresBuild: true optional: true + /@radix-ui/number@1.0.1: + resolution: {integrity: sha512-T5gIdVO2mmPW3NNhjNgEP3cqMXjXL9UbO0BzWcXfvdBs+BohbQxvd/K5hSVKmn9/lbTdsQVKbUcP5WLCwvUbBg==} + dependencies: + '@babel/runtime': 7.24.4 + dev: false + /@radix-ui/primitive@1.0.1: resolution: {integrity: sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==} dependencies: @@ -1177,6 +1206,27 @@ packages: react: 18.2.0 dev: false + /@radix-ui/react-label@2.0.2(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-N5ehvlM7qoTLx7nWPodsPYPgMzA5WM8zZChQg8nyFJKnDO5WHdba1vv5/H6IO5LtJMfD2Q3wh1qHFGNtK0w3bQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.24.4 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.78 + '@types/react-dom': 18.2.25 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@radix-ui/react-menu@2.0.6(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-BVkFLS+bUC8HcImkRKPSiVumA1VPOOEC5WBMiT+QAVsPzW1FJzI9KnqgGxVDPBcql5xXrHkD3JOVoXWEXD8SYA==} peerDependencies: @@ -1338,6 +1388,47 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@radix-ui/react-select@2.0.0(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-RH5b7af4oHtkcHS7pG6Sgv5rk5Wxa7XI8W5gvB1N/yiuDGZxko1ynvOiVhFM7Cis2A8zxF9bTOUVbRDzPepe6w==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.24.4 + '@radix-ui/number': 1.0.1 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.78)(react@18.2.0) + '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.78 + '@types/react-dom': 18.2.25 + aria-hidden: 1.2.4 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-remove-scroll: 2.5.5(@types/react@18.2.78)(react@18.2.0) + dev: false + /@radix-ui/react-separator@1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.78)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-itYmTy/kokS21aiV5+Z56MZB54KrhPgn6eHDKkFeOLR34HMN2s8PaN47qZZAGnvupcjxHaFZnW4pQEh0BvvVuw==} peerDependencies: @@ -1496,6 +1587,20 @@ packages: react: 18.2.0 dev: false + /@radix-ui/react-use-previous@1.0.1(@types/react@18.2.78)(react@18.2.0): + resolution: {integrity: sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.24.4 + '@types/react': 18.2.78 + react: 18.2.0 + dev: false + /@radix-ui/react-use-rect@1.0.1(@types/react@18.2.78)(react@18.2.0): resolution: {integrity: sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw==} peerDependencies: @@ -4394,8 +4499,8 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false - /next@14.2.1(@babel/core@7.24.4)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-SF3TJnKdH43PMkCcErLPv+x/DY1YCklslk3ZmwaVoyUfDgHKexuKlf9sEfBQ69w+ue8jQ3msLb+hSj1T19hGag==} + /next@14.2.2(@babel/core@7.24.4)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-oGwUaa2bCs47FbuxWMpOoXtBMPYpvTPgdZr3UAo+pu7Ns00z9otmYpoeV1HEiYL06AlRQQIA/ypK526KjJfaxg==} engines: {node: '>=18.17.0'} hasBin: true peerDependencies: @@ -4412,7 +4517,7 @@ packages: sass: optional: true dependencies: - '@next/env': 14.2.1 + '@next/env': 14.2.2 '@swc/helpers': 0.5.5 busboy: 1.6.0 caniuse-lite: 1.0.30001609 @@ -4422,15 +4527,15 @@ packages: react-dom: 18.2.0(react@18.2.0) styled-jsx: 5.1.1(@babel/core@7.24.4)(react@18.2.0) optionalDependencies: - '@next/swc-darwin-arm64': 14.2.1 - '@next/swc-darwin-x64': 14.2.1 - '@next/swc-linux-arm64-gnu': 14.2.1 - '@next/swc-linux-arm64-musl': 14.2.1 - '@next/swc-linux-x64-gnu': 14.2.1 - '@next/swc-linux-x64-musl': 14.2.1 - '@next/swc-win32-arm64-msvc': 14.2.1 - '@next/swc-win32-ia32-msvc': 14.2.1 - '@next/swc-win32-x64-msvc': 14.2.1 + '@next/swc-darwin-arm64': 14.2.2 + '@next/swc-darwin-x64': 14.2.2 + '@next/swc-linux-arm64-gnu': 14.2.2 + '@next/swc-linux-arm64-musl': 14.2.2 + '@next/swc-linux-x64-gnu': 14.2.2 + '@next/swc-linux-x64-musl': 14.2.2 + '@next/swc-win32-arm64-msvc': 14.2.2 + '@next/swc-win32-ia32-msvc': 14.2.2 + '@next/swc-win32-x64-msvc': 14.2.2 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros @@ -4819,6 +4924,15 @@ packages: scheduler: 0.23.0 dev: false + /react-hook-form@7.51.3(react@18.2.0): + resolution: {integrity: sha512-cvJ/wbHdhYx8aviSWh28w9ImjmVsb5Y05n1+FW786vEZQJV5STNM0pW6ujS+oiBecb0ARBxJFyAnXj9+GHXACQ==} + engines: {node: '>=12.22.0'} + peerDependencies: + react: ^16.8.0 || ^17 || ^18 + dependencies: + react: 18.2.0 + dev: false + /react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} dev: true @@ -5765,3 +5879,7 @@ packages: /yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + + /zod@3.22.4: + resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} + dev: false diff --git a/src/app/(pages)/server/[platform]/[[...hostname]]/page.tsx b/src/app/(pages)/server/[platform]/[[...hostname]]/page.tsx index 309dbf9..cc54df1 100644 --- a/src/app/(pages)/server/[platform]/[[...hostname]]/page.tsx +++ b/src/app/(pages)/server/[platform]/[[...hostname]]/page.tsx @@ -116,7 +116,7 @@ export default async function Page({ params: { platform, hostname } }: Params):

Lookup a {invalidPlatform ? "" : capitalizeFirstLetter(platform)} Server

You can enter a server hostname to get information about the server.

- + {error && } diff --git a/src/app/components/code-dialog.tsx b/src/app/components/code-dialog.tsx index aea1ec9..f8b2171 100644 --- a/src/app/components/code-dialog.tsx +++ b/src/app/components/code-dialog.tsx @@ -1,6 +1,6 @@ import { ReactElement } from "react"; import SyntaxHighlighter from "react-syntax-highlighter"; -import { atomOneDarkReasonable } from "react-syntax-highlighter/dist/esm/styles/hljs"; +import { atelierSeasideDark } from "react-syntax-highlighter/dist/esm/styles/hljs"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from "./ui/dialog"; type CodeDialogProps = { @@ -21,7 +21,7 @@ export function CodeDialog({ title, description, code, children }: CodeDialogPro + Copied {content} to your clipboard +

+ ), duration: 5000, }); }} diff --git a/src/app/components/navbar.tsx b/src/app/components/navbar.tsx index 261b312..44c54ef 100644 --- a/src/app/components/navbar.tsx +++ b/src/app/components/navbar.tsx @@ -27,9 +27,11 @@ export default function NavBar(): ReactElement {
- {pages.map((page, index) => { - return ; - })} +
+ {pages.map((page, index) => { + return ; + })} +
diff --git a/src/app/components/player/lookup-player.tsx b/src/app/components/player/lookup-player.tsx index eba140a..6300c96 100644 --- a/src/app/components/player/lookup-player.tsx +++ b/src/app/components/player/lookup-player.tsx @@ -3,26 +3,28 @@ import { useToast } from "@/common/use-toast"; import { getPlayer } from "mcutils-library"; import { useRouter } from "next/navigation"; -import { ReactElement, useState } from "react"; +import { ReactElement } from "react"; import { Button } from "../ui/button"; import { Input } from "../ui/input"; -import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip"; +import { Label } from "../ui/label"; export function LookupPlayer(): ReactElement { const router = useRouter(); const { toast } = useToast(); - const [id, setId] = useState(""); /** - * Lookup a player + * Lookup a server based on the platform + * + * @param platform the server platform + * @param query the query to lookup */ - const lookupPlayer = async () => { - if (!id || id.length === 0) { + const lookupPlayer = async (query: string) => { + if (!query || query.length === 0) { return; } try { - await getPlayer(id); + await getPlayer(query); } catch (err) { toast({ title: "Error", @@ -33,32 +35,24 @@ export function LookupPlayer(): ReactElement { return; } - router.push(`/player/${id}`); + router.push(`/player/${query}`); }; return ( -
event.preventDefault()}> - { - setId(event.target.value); - }} - maxLength={36} - /> - - - - - -

Click to lookup the player

-
-
+ { + lookupPlayer(form.get("query") as string); + }} + > +
+
+ + +
+
+ +
); } diff --git a/src/app/components/server/lookup-server.tsx b/src/app/components/server/lookup-server.tsx index 74dcaf1..029a435 100644 --- a/src/app/components/server/lookup-server.tsx +++ b/src/app/components/server/lookup-server.tsx @@ -1,40 +1,35 @@ "use client"; -import { capitalizeFirstLetter } from "@/common/string-utils"; import { useToast } from "@/common/use-toast"; import { ServerPlatform, getServer } from "mcutils-library"; import { useRouter } from "next/navigation"; -import { ReactElement, useState } from "react"; +import { ReactElement } from "react"; import { Button } from "../ui/button"; import { Input } from "../ui/input"; -import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip"; +import { Label } from "../ui/label"; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../ui/select"; -export function LookupServer(): ReactElement { +type LookupServerProps = { + currentPlatform: string; +}; + +export function LookupServer({ currentPlatform }: LookupServerProps): ReactElement { const router = useRouter(); const { toast } = useToast(); - const [hostname, setHostname] = useState(""); - - /** - * Set the hostname value - * - * @param event the input event - */ - const setHostnameValue = (event: React.ChangeEvent) => { - setHostname(event.target.value); - }; /** * Lookup a server based on the platform * * @param platform the server platform + * @param query the query to lookup */ - const lookupServer = async (platform: ServerPlatform) => { - if (!hostname || hostname.length === 0) { + const lookupServer = async (platform: ServerPlatform, query: string) => { + if (!query || query.length === 0) { return; } try { - await getServer(platform, hostname); + await getServer(platform, query); } catch (err) { toast({ title: "Error", @@ -45,44 +40,37 @@ export function LookupServer(): ReactElement { return; } - router.push(`/server/${platform}/${hostname}`); - }; - - const LookupButton = ({ platform }: { platform: ServerPlatform }): ReactElement => { - const name = capitalizeFirstLetter(platform); - return ( - - - - - -

Click to lookup the server as a {name} server

-
-
- ); + router.push(`/server/${platform}/${query}`); }; return (
event.preventDefault()} + className="flex flex-col gap-2 justify-center items-center mt-4" + action={(form: FormData) => { + lookupServer(form.get("platform") as ServerPlatform, form.get("query") as string); + }} > -
- - +
+ + +
+ +
+ + +
+ +
); } diff --git a/src/app/components/ui/label.tsx b/src/app/components/ui/label.tsx new file mode 100644 index 0000000..06ad59c --- /dev/null +++ b/src/app/components/ui/label.tsx @@ -0,0 +1,26 @@ +"use client" + +import * as React from "react" +import * as LabelPrimitive from "@radix-ui/react-label" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/common/utils" + +const labelVariants = cva( + "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" +) + +const Label = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & + VariantProps +>(({ className, ...props }, ref) => ( + +)) +Label.displayName = LabelPrimitive.Root.displayName + +export { Label } diff --git a/src/app/components/ui/select.tsx b/src/app/components/ui/select.tsx new file mode 100644 index 0000000..88ea435 --- /dev/null +++ b/src/app/components/ui/select.tsx @@ -0,0 +1,160 @@ +"use client" + +import * as React from "react" +import * as SelectPrimitive from "@radix-ui/react-select" +import { Check, ChevronDown, ChevronUp } from "lucide-react" + +import { cn } from "@/common/utils" + +const Select = SelectPrimitive.Root + +const SelectGroup = SelectPrimitive.Group + +const SelectValue = SelectPrimitive.Value + +const SelectTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + span]:line-clamp-1", + className + )} + {...props} + > + {children} + + + + +)) +SelectTrigger.displayName = SelectPrimitive.Trigger.displayName + +const SelectScrollUpButton = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + +)) +SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName + +const SelectScrollDownButton = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + +)) +SelectScrollDownButton.displayName = + SelectPrimitive.ScrollDownButton.displayName + +const SelectContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, position = "popper", ...props }, ref) => ( + + + + + {children} + + + + +)) +SelectContent.displayName = SelectPrimitive.Content.displayName + +const SelectLabel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +SelectLabel.displayName = SelectPrimitive.Label.displayName + +const SelectItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + + + + + {children} + +)) +SelectItem.displayName = SelectPrimitive.Item.displayName + +const SelectSeparator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +SelectSeparator.displayName = SelectPrimitive.Separator.displayName + +export { + Select, + SelectGroup, + SelectValue, + SelectTrigger, + SelectContent, + SelectLabel, + SelectItem, + SelectSeparator, + SelectScrollUpButton, + SelectScrollDownButton, +}