From fba5ced20eb84b8bf99726b6efe6181e5f9e6005 Mon Sep 17 00:00:00 2001 From: IdkGoodName <31628630+IdkGoodName@users.noreply.github.com> Date: Mon, 8 Sep 2025 13:45:05 +1000 Subject: [PATCH 01/14] feat: use fontsource instead of Google fonts --- sites/app.campground.gg/package-lock.json | 632 +++++++++++++++++++++- sites/app.campground.gg/package.json | 5 + sites/app.campground.gg/src/App.scss | 10 +- sites/app.campground.gg/src/App.tsx | 10 + 4 files changed, 629 insertions(+), 28 deletions(-) diff --git a/sites/app.campground.gg/package-lock.json b/sites/app.campground.gg/package-lock.json index aab0a14..1abde35 100644 --- a/sites/app.campground.gg/package-lock.json +++ b/sites/app.campground.gg/package-lock.json @@ -8,6 +8,10 @@ "name": "react-ts", "version": "0.0.0", "dependencies": { + "@emotion/react": "^11.14.0", + "@emotion/styled": "^11.14.1", + "@fontsource/nunito-sans": "^5.2.6", + "@fontsource/quicksand": "^5.2.9", "@mantine/code-highlight": "^7.17.3", "@mantine/core": "^7.17.3", "@mantine/dates": "^7.17.3", @@ -17,6 +21,7 @@ "@mantine/modals": "^7.17.3", "@mantine/notifications": "^7.17.3", "@mantine/tiptap": "^7.17.3", + "@mui/joy": "^5.0.0-beta.52", "@tabler/icons-react": "^3.34.1", "@tiptap/extension-link": "^2.11.5", "@tiptap/pm": "^2.11.5", @@ -72,7 +77,6 @@ "version": "7.26.2", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.25.9", @@ -128,7 +132,6 @@ "version": "7.27.0", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.0.tgz", "integrity": "sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==", - "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.27.0", @@ -162,7 +165,6 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", - "dev": true, "license": "MIT", "dependencies": { "@babel/traverse": "^7.25.9", @@ -204,7 +206,6 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -214,7 +215,6 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -248,7 +248,6 @@ "version": "7.27.0", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz", "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==", - "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.27.0" @@ -308,7 +307,6 @@ "version": "7.27.0", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz", "integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==", - "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.26.2", @@ -323,7 +321,6 @@ "version": "7.27.0", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.0.tgz", "integrity": "sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==", - "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.26.2", @@ -342,7 +339,6 @@ "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -352,7 +348,6 @@ "version": "7.27.0", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz", "integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.25.9", @@ -362,6 +357,158 @@ "node": ">=6.9.0" } }, + "node_modules/@emotion/babel-plugin": { + "version": "11.13.5", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz", + "integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/serialize": "^1.3.3", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "license": "MIT" + }, + "node_modules/@emotion/cache": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz", + "integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0", + "@emotion/sheet": "^1.4.0", + "@emotion/utils": "^1.4.2", + "@emotion/weak-memoize": "^0.4.0", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", + "license": "MIT" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.4.0.tgz", + "integrity": "sha512-QgD4fyscGcbbKwJmqNvUMSE02OsHUa+lAWKdEUIJKgqe5IwRSKd7+KhibEWdaKwgjLj0DRSHA9biAIqGBk05lw==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", + "license": "MIT" + }, + "node_modules/@emotion/react": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz", + "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/cache": "^11.14.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2", + "@emotion/weak-memoize": "^0.4.0", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz", + "integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==", + "license": "MIT", + "dependencies": { + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/unitless": "^0.10.0", + "@emotion/utils": "^1.4.2", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", + "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", + "license": "MIT" + }, + "node_modules/@emotion/styled": { + "version": "11.14.1", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.1.tgz", + "integrity": "sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/is-prop-valid": "^1.3.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", + "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==", + "license": "MIT" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz", + "integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz", + "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==", + "license": "MIT" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", + "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", + "license": "MIT" + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.1.tgz", @@ -966,6 +1113,24 @@ "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==", "license": "MIT" }, + "node_modules/@fontsource/nunito-sans": { + "version": "5.2.6", + "resolved": "https://registry.npmjs.org/@fontsource/nunito-sans/-/nunito-sans-5.2.6.tgz", + "integrity": "sha512-f3qQqoZXtJPqhrh1M/CTeFZnRsZj7fEnILmGmbyNdlx9GrddQ3avQWwsa0cnBkG5UFGWvnzcfuJp1s+PNHjBsg==", + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, + "node_modules/@fontsource/quicksand": { + "version": "5.2.9", + "resolved": "https://registry.npmjs.org/@fontsource/quicksand/-/quicksand-5.2.9.tgz", + "integrity": "sha512-/oXf8596gz6Looap/9WWr4sFsRaThWGhX979ssU3azqG08mx8Gg4ubO2h8WmeD8IUnq5xJ6tChugZ9qNJO4dVQ==", + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, "node_modules/@formatjs/ecma402-abstract": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.3.4.tgz", @@ -1108,7 +1273,6 @@ "version": "0.3.8", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.2.1", @@ -1123,7 +1287,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -1133,7 +1296,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -1143,14 +1305,12 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -1296,6 +1456,240 @@ "react-dom": "^18.x || ^19.x" } }, + "node_modules/@mui/base": { + "version": "5.0.0-beta.40-1", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40-1.tgz", + "integrity": "sha512-agKXuNNy0bHUmeU7pNmoZwNFr7Hiyhojkb9+2PVyDG5+6RafYuyMgbrav8CndsB7KUc/U51JAw9vKNDLYBzaUA==", + "deprecated": "This package has been replaced by @base-ui-components/react", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@floating-ui/react-dom": "^2.0.8", + "@mui/types": "~7.2.15", + "@mui/utils": "^5.17.1", + "@popperjs/core": "^2.11.8", + "clsx": "^2.1.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/core-downloads-tracker": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.18.0.tgz", + "integrity": "sha512-jbhwoQ1AY200PSSOrNXmrFCaSDSJWP7qk6urkTmIirvRXDROkqe+QwcLlUiw/PrREwsIF/vm3/dAXvjlMHF0RA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + } + }, + "node_modules/@mui/joy": { + "version": "5.0.0-beta.52", + "resolved": "https://registry.npmjs.org/@mui/joy/-/joy-5.0.0-beta.52.tgz", + "integrity": "sha512-e8jQanA5M1f/X52mJrw0UIW8Er7EAHuLuigmGFw7yIsAgIluhIP4rZ7JcbVrUi6z5Gk0weC9QWUUtjLejAbO8g==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/base": "5.0.0-beta.40-1", + "@mui/core-downloads-tracker": "^5.17.1", + "@mui/system": "^5.17.1", + "@mui/types": "~7.2.15", + "@mui/utils": "^5.17.1", + "clsx": "^2.1.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/private-theming": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.17.1.tgz", + "integrity": "sha512-XMxU0NTYcKqdsG8LRmSoxERPXwMbp16sIXPcLVgLGII/bVNagX0xaheWAwFv8+zDK7tI3ajllkuD3GZZE++ICQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/utils": "^5.17.1", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.18.0.tgz", + "integrity": "sha512-BN/vKV/O6uaQh2z5rXV+MBlVrEkwoS/TK75rFQ2mjxA7+NBo8qtTAOA4UaM0XeJfn7kh2wZ+xQw2HAx0u+TiBg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@emotion/cache": "^11.13.5", + "@emotion/serialize": "^1.3.3", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.18.0.tgz", + "integrity": "sha512-ojZGVcRWqWhu557cdO3pWHloIGJdzVtxs3rk0F9L+x55LsUjcMUVkEhiF7E4TMxZoF9MmIHGGs0ZX3FDLAf0Xw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/private-theming": "^5.17.1", + "@mui/styled-engine": "^5.18.0", + "@mui/types": "~7.2.15", + "@mui/utils": "^5.17.1", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.2.24", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.24.tgz", + "integrity": "sha512-3c8tRt/CbWZ+pEg7QpSwbdxOk36EfmhbKf6AGZsD1EcLDLTSZoxxJ86FVtcjxvjuhdyBiWKSTGZFaXCnidO2kw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.17.1.tgz", + "integrity": "sha512-jEZ8FTqInt2WzxDV8bhImWBqeQRD99c/id/fq83H0ER9tFl+sfZlaAoCdznGvbSQQ9ividMxqSV2c7cC1vBcQg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/types": "~7.2.15", + "@types/prop-types": "^15.7.12", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-is": "^19.0.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils/node_modules/react-is": { + "version": "19.1.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.1.1.tgz", + "integrity": "sha512-tr41fA15Vn8p4X9ntI+yCyeGSf1TlYaY5vlTZfQmeLBrFo3psOPX6HhTDnFNL9uj3EhP0KAQ80cugCl4b4BERA==", + "license": "MIT" + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -2438,6 +2832,18 @@ "undici-types": "~6.20.0" } }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "license": "MIT" + }, + "node_modules/@types/prop-types": { + "version": "15.7.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "license": "MIT" + }, "node_modules/@types/react": { "version": "19.0.12", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.0.12.tgz", @@ -2777,6 +3183,21 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "license": "Python-2.0" }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -2856,7 +3277,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -3002,6 +3422,31 @@ "node": ">=18" } }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "license": "MIT", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cosmiconfig/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, "node_modules/crelt": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", @@ -3052,7 +3497,6 @@ "version": "4.4.0", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -3127,6 +3571,15 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, "node_modules/esbuild": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz", @@ -3449,6 +3902,12 @@ "node": ">=8" } }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "license": "MIT" + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -3515,6 +3974,15 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -3583,6 +4051,18 @@ "node": ">=8" } }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/highlight.js": { "version": "11.11.1", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz", @@ -3622,7 +4102,6 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "dev": true, "license": "MIT", "dependencies": { "parent-module": "^1.0.0", @@ -3657,6 +4136,12 @@ "tslib": "^2.8.0" } }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -3669,6 +4154,21 @@ "node": ">=8" } }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -3729,7 +4229,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "dev": true, "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -3745,6 +4244,12 @@ "dev": true, "license": "MIT" }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT" + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -3817,6 +4322,12 @@ "node": ">= 0.8.0" } }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" + }, "node_modules/linkify-it": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", @@ -3939,7 +4450,6 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, "license": "MIT" }, "node_modules/nanoid": { @@ -4071,7 +4581,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, "license": "MIT", "dependencies": { "callsites": "^3.0.0" @@ -4080,6 +4589,24 @@ "node": ">=6" } }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -4100,6 +4627,21 @@ "node": ">=8" } }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -4762,11 +5304,30 @@ "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", "license": "MIT" }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -4952,6 +5513,15 @@ "node": ">=8" } }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -4974,6 +5544,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", + "license": "MIT" + }, "node_modules/sugarss": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/sugarss/-/sugarss-4.0.1.tgz", @@ -5004,6 +5580,18 @@ "node": ">=8" } }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/tabbable": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", diff --git a/sites/app.campground.gg/package.json b/sites/app.campground.gg/package.json index 6f836b8..36bea15 100644 --- a/sites/app.campground.gg/package.json +++ b/sites/app.campground.gg/package.json @@ -10,6 +10,10 @@ "preview": "vite preview" }, "dependencies": { + "@emotion/react": "^11.14.0", + "@emotion/styled": "^11.14.1", + "@fontsource/nunito-sans": "^5.2.6", + "@fontsource/quicksand": "^5.2.9", "@mantine/code-highlight": "^7.17.3", "@mantine/core": "^7.17.3", "@mantine/dates": "^7.17.3", @@ -19,6 +23,7 @@ "@mantine/modals": "^7.17.3", "@mantine/notifications": "^7.17.3", "@mantine/tiptap": "^7.17.3", + "@mui/joy": "^5.0.0-beta.52", "@tabler/icons-react": "^3.34.1", "@tiptap/extension-link": "^2.11.5", "@tiptap/pm": "^2.11.5", diff --git a/sites/app.campground.gg/src/App.scss b/sites/app.campground.gg/src/App.scss index 513b3b3..5ef9920 100644 --- a/sites/app.campground.gg/src/App.scss +++ b/sites/app.campground.gg/src/App.scss @@ -1,15 +1,13 @@ @use "css/index.scss"; -@import url('https://fonts.googleapis.com/css2?family=Quicksand:wght@300..700&display=swap'); -@import url('https://fonts.googleapis.com/css2?family=Nunito+Sans:ital,opsz,wght@0,6..12,200..1000;1,6..12,200..1000&display=swap'); // TODO: Add variables here. -:root[data-mantine-color-scheme='light'] { +// :root[data-mantine-color-scheme='light'] { -} +// } -:root[data-mantine-color-scheme='dark'] { +// :root[data-mantine-color-scheme='dark'] { -} +// } * { diff --git a/sites/app.campground.gg/src/App.tsx b/sites/app.campground.gg/src/App.tsx index 9d92e68..f5d1c76 100644 --- a/sites/app.campground.gg/src/App.tsx +++ b/sites/app.campground.gg/src/App.tsx @@ -4,6 +4,15 @@ import { RouterProvider, } from "react-router"; +import "@fontsource/nunito-sans/500.css"; +import "@fontsource/nunito-sans/500-italic.css"; +import "@fontsource/nunito-sans/700.css"; +import "@fontsource/nunito-sans/700-italic.css"; +import "@fontsource/nunito-sans/900.css"; +import "@fontsource/nunito-sans/900-italic.css"; +import "@fontsource/quicksand/400.css"; +import "@fontsource/quicksand/500.css"; +import "@fontsource/quicksand/700.css"; import './App.scss' import '@mantine/core/styles.css'; import '@mantine/notifications/styles.css'; @@ -16,6 +25,7 @@ import { SessionProvider } from './session'; import Index from './routes/Index'; import theme from './theme'; + function App() { const router = createBrowserRouter([ { From 7549c02dcd0bd43f5cfa0475ea2918e1dfb94027 Mon Sep 17 00:00:00 2001 From: IdkGoodName <31628630+IdkGoodName@users.noreply.github.com> Date: Tue, 9 Sep 2025 19:14:02 +1000 Subject: [PATCH 02/14] feat: replace Mantine with MUI, add proper theming --- lang/en-US.json | 2 +- sites/app.campground.gg/src/App.scss | 13 +-- sites/app.campground.gg/src/App.tsx | 25 +++--- .../src/components/BrandLogo.tsx | 29 ------- .../src/components/PrimaryButton.tsx | 22 +++++ .../src/components/index/BrandLogo.tsx | 30 +++++++ .../components/{ => index}/IndexFooter.tsx | 32 ++++++- .../{ => index}/IndexFooterItem.tsx | 13 +-- .../{ => index}/IndexFooterSection.tsx | 12 +-- .../components/{ => index}/IndexNavbar.tsx | 25 +++--- .../{ => index}/IndexNavbarItem.tsx | 9 +- .../components/index/IndexNavbarPrimary.tsx | 26 ++++++ .../{ => index}/IndexPageWrapper.tsx | 14 ++-- sites/app.campground.gg/src/css/index.scss | 4 - sites/app.campground.gg/src/routes/Index.tsx | 50 +++++++---- sites/app.campground.gg/src/theme.ts | 19 ----- sites/app.campground.gg/src/theme/color.ts | 51 ++++++++++++ sites/app.campground.gg/src/theme/dark.ts | 47 +++++++++++ sites/app.campground.gg/src/theme/font.ts | 16 ++++ sites/app.campground.gg/src/theme/gen.ts | 52 ++++++++++++ sites/app.campground.gg/src/theme/index.ts | 83 +++++++++++++++++++ sites/app.campground.gg/src/theme/light.ts | 12 +++ 22 files changed, 454 insertions(+), 132 deletions(-) delete mode 100644 sites/app.campground.gg/src/components/BrandLogo.tsx create mode 100644 sites/app.campground.gg/src/components/PrimaryButton.tsx create mode 100644 sites/app.campground.gg/src/components/index/BrandLogo.tsx rename sites/app.campground.gg/src/components/{ => index}/IndexFooter.tsx (60%) rename sites/app.campground.gg/src/components/{ => index}/IndexFooterItem.tsx (52%) rename sites/app.campground.gg/src/components/{ => index}/IndexFooterSection.tsx (69%) rename sites/app.campground.gg/src/components/{ => index}/IndexNavbar.tsx (63%) rename sites/app.campground.gg/src/components/{ => index}/IndexNavbarItem.tsx (63%) create mode 100644 sites/app.campground.gg/src/components/index/IndexNavbarPrimary.tsx rename sites/app.campground.gg/src/components/{ => index}/IndexPageWrapper.tsx (53%) delete mode 100644 sites/app.campground.gg/src/theme.ts create mode 100644 sites/app.campground.gg/src/theme/color.ts create mode 100644 sites/app.campground.gg/src/theme/dark.ts create mode 100644 sites/app.campground.gg/src/theme/font.ts create mode 100644 sites/app.campground.gg/src/theme/gen.ts create mode 100644 sites/app.campground.gg/src/theme/index.ts create mode 100644 sites/app.campground.gg/src/theme/light.ts diff --git a/lang/en-US.json b/lang/en-US.json index 5265cde..690fca6 100644 --- a/lang/en-US.json +++ b/lang/en-US.json @@ -29,7 +29,7 @@ } }, "home": { - "title": "Gather around the fire", + "title": "Gather around the fire, friends", "description": "Campground is the best place for you and your friends to hang out, create communities, and have fun without any hassle!", "download": "Download Campground", "open": "Open Campground" diff --git a/sites/app.campground.gg/src/App.scss b/sites/app.campground.gg/src/App.scss index 5ef9920..a5ac135 100644 --- a/sites/app.campground.gg/src/App.scss +++ b/sites/app.campground.gg/src/App.scss @@ -1,14 +1,9 @@ @use "css/index.scss"; -// TODO: Add variables here. -// :root[data-mantine-color-scheme='light'] { - -// } - -// :root[data-mantine-color-scheme='dark'] { - -// } - +html, body, #root { + width: 100%; + height: 100%; +} * { font-family: "Nunito Sans", sans-serif; diff --git a/sites/app.campground.gg/src/App.tsx b/sites/app.campground.gg/src/App.tsx index f5d1c76..b8439e6 100644 --- a/sites/app.campground.gg/src/App.tsx +++ b/sites/app.campground.gg/src/App.tsx @@ -1,4 +1,4 @@ -import { ColorSchemeScript, MantineProvider } from '@mantine/core'; +// import { ColorSchemeScript, MantineProvider } from '@mantine/core'; import { createBrowserRouter, RouterProvider, @@ -23,7 +23,9 @@ import '@mantine/dropzone/styles.css'; import { IntlProvider } from './i18n'; import { SessionProvider } from './session'; import Index from './routes/Index'; -import theme from './theme'; +import { CssBaseline, CssVarsProvider, StyledEngineProvider } from '@mui/joy'; +import InitColorSchemeScript from '@mui/joy/InitColorSchemeScript'; +import theme from "./theme"; function App() { @@ -36,14 +38,17 @@ function App() { return ( <> - - - - - - - - + + + + + + + + + + + ) } diff --git a/sites/app.campground.gg/src/components/BrandLogo.tsx b/sites/app.campground.gg/src/components/BrandLogo.tsx deleted file mode 100644 index 1a50c7a..0000000 --- a/sites/app.campground.gg/src/components/BrandLogo.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { Group, Image, MantineSize, Text, UnstyledButton } from "@mantine/core"; - -export type Props = { - includeText?: boolean; - size?: MantineSize; -}; - -const sizeToFz: Record = { - "xl": "h1", - "lg": "h2", - "md": "h3", - "sm": "h4", - "xs": "h5" -}; - -export default function BrandLogo({ size, includeText }: Props) { - const fz = sizeToFz[size ?? "md"]; - - return ( - - - - {includeText && - Campground - } - - - ) -} \ No newline at end of file diff --git a/sites/app.campground.gg/src/components/PrimaryButton.tsx b/sites/app.campground.gg/src/components/PrimaryButton.tsx new file mode 100644 index 0000000..776e388 --- /dev/null +++ b/sites/app.campground.gg/src/components/PrimaryButton.tsx @@ -0,0 +1,22 @@ +import { Button, styled } from "@mui/joy"; + +const PrimaryButton = styled(Button)(({ theme }) => ({ + background: `linear-gradient(30deg, ${theme.vars.palette.primary[500]}, ${theme.vars.palette.secondary[500]})`, + boxShadow: `0 0 5px ${theme.vars.palette.primary[500]}`, + "::after": { + content: '""', + zIndex: 1, + top: 0, + left: 0, + right: 0, + bottom: 0, + backgroundColor: "transparent", + position: "absolute", + transition: "background 0.3s", + borderRadius: "var(--Button-radius, var(--joy-radius-sm))", + }, + ":hover::after": { + backgroundColor: "#FFF3" + } +})); +export default PrimaryButton; \ No newline at end of file diff --git a/sites/app.campground.gg/src/components/index/BrandLogo.tsx b/sites/app.campground.gg/src/components/index/BrandLogo.tsx new file mode 100644 index 0000000..bcdf273 --- /dev/null +++ b/sites/app.campground.gg/src/components/index/BrandLogo.tsx @@ -0,0 +1,30 @@ +import { Link, Stack, Typography } from "@mui/joy"; +import { DefaultTypographySystem } from "@mui/joy/styles/types"; + +export type Props = { + includeText?: boolean; + size?: "xl" | "lg" | "md" | "sm" | "xs"; +}; + +const sizeToFz: Record<"xl" | "lg" | "md" | "sm" | "xs", keyof DefaultTypographySystem> = { + "xl": "h1", + "lg": "h2", + "md": "h3", + "sm": "h4", + "xs": "title-sm" +}; + +export default function BrandLogo({ size, includeText }: Props) { + const fz = sizeToFz[size ?? "md"]; + + return ( + + + + {includeText && + Campground + } + + + ) +} \ No newline at end of file diff --git a/sites/app.campground.gg/src/components/IndexFooter.tsx b/sites/app.campground.gg/src/components/index/IndexFooter.tsx similarity index 60% rename from sites/app.campground.gg/src/components/IndexFooter.tsx rename to sites/app.campground.gg/src/components/index/IndexFooter.tsx index c89369e..e7a960f 100644 --- a/sites/app.campground.gg/src/components/IndexFooter.tsx +++ b/sites/app.campground.gg/src/components/index/IndexFooter.tsx @@ -1,10 +1,10 @@ import React from "react"; import BrandLogo from "./BrandLogo"; import IndexFooterItem from "./IndexFooterItem"; -import { SimpleGrid, Stack } from "@mantine/core"; import IndexFooterSection from "./IndexFooterSection"; import { FormattedMessage } from "react-intl"; import { IconBrandBluesky, IconBrandDiscord, IconBrandGithub, IconBrandX } from "@tabler/icons-react"; +import { Grid, Stack } from "@mui/joy"; export type Props = { }; @@ -15,9 +15,9 @@ export default class IndexFooter extends React.Component { } render() { return ( - + - + } href="https://github.com/Project-Campground">GitHub } href="https://bsky.app/profile/campground.gg">Bluesky @@ -46,7 +46,31 @@ export default class IndexFooter extends React.Component { - + + + + + + + + + + + + + + + + + + + + + + + + + ); } diff --git a/sites/app.campground.gg/src/components/IndexFooterItem.tsx b/sites/app.campground.gg/src/components/index/IndexFooterItem.tsx similarity index 52% rename from sites/app.campground.gg/src/components/IndexFooterItem.tsx rename to sites/app.campground.gg/src/components/index/IndexFooterItem.tsx index 1762506..a056835 100644 --- a/sites/app.campground.gg/src/components/IndexFooterItem.tsx +++ b/sites/app.campground.gg/src/components/index/IndexFooterItem.tsx @@ -1,4 +1,4 @@ -import { Group, Text, UnstyledButton } from "@mantine/core"; +import { Link } from "@mui/joy"; import React, { ReactNode } from "react"; export type Props = { @@ -15,14 +15,9 @@ export default class IndexFooterItem extends React.Component { const { icon, href, children } = this.props; return ( - - - {icon} - - {children} - - - + + {children} + ); } } \ No newline at end of file diff --git a/sites/app.campground.gg/src/components/IndexFooterSection.tsx b/sites/app.campground.gg/src/components/index/IndexFooterSection.tsx similarity index 69% rename from sites/app.campground.gg/src/components/IndexFooterSection.tsx rename to sites/app.campground.gg/src/components/index/IndexFooterSection.tsx index af0686e..18a6863 100644 --- a/sites/app.campground.gg/src/components/IndexFooterSection.tsx +++ b/sites/app.campground.gg/src/components/index/IndexFooterSection.tsx @@ -1,4 +1,4 @@ -import { Stack, Text } from "@mantine/core"; +import { Grid, Stack, Typography } from "@mui/joy"; import React, { ReactNode } from "react"; import { FormattedMessage } from "react-intl"; @@ -15,14 +15,14 @@ export default class IndexFooterSection extends React.Component { const { header, children } = this.props; return ( - - + + - - + + {children} - + ); } } \ No newline at end of file diff --git a/sites/app.campground.gg/src/components/IndexNavbar.tsx b/sites/app.campground.gg/src/components/index/IndexNavbar.tsx similarity index 63% rename from sites/app.campground.gg/src/components/IndexNavbar.tsx rename to sites/app.campground.gg/src/components/index/IndexNavbar.tsx index 64b8e89..5875435 100644 --- a/sites/app.campground.gg/src/components/IndexNavbar.tsx +++ b/sites/app.campground.gg/src/components/index/IndexNavbar.tsx @@ -1,8 +1,9 @@ import React from "react"; import BrandLogo from "./BrandLogo"; import IndexNavbarItem from "./IndexNavbarItem"; -import { Group } from "@mantine/core"; import { FormattedMessage } from "react-intl"; +import { Link, Stack } from "@mui/joy"; +import IndexNavbarPrimary from "./IndexNavbarPrimary"; export type Props = { page: string; @@ -14,11 +15,11 @@ export default class IndexNavbar extends React.Component { } render() { return ( - - - - - + + + + + @@ -34,16 +35,16 @@ export default class IndexNavbar extends React.Component { - - + + - + - - - + + + ); } } \ No newline at end of file diff --git a/sites/app.campground.gg/src/components/IndexNavbarItem.tsx b/sites/app.campground.gg/src/components/index/IndexNavbarItem.tsx similarity index 63% rename from sites/app.campground.gg/src/components/IndexNavbarItem.tsx rename to sites/app.campground.gg/src/components/index/IndexNavbarItem.tsx index b9cb17b..a027712 100644 --- a/sites/app.campground.gg/src/components/IndexNavbarItem.tsx +++ b/sites/app.campground.gg/src/components/index/IndexNavbarItem.tsx @@ -1,4 +1,4 @@ -import { Button, ButtonVariant } from "@mantine/core"; +import { Button, ColorPaletteProp, VariantProp } from "@mui/joy"; import React, { ReactNode } from "react"; export type Props = { @@ -6,7 +6,8 @@ export type Props = { href: string; active?: boolean; icon?: ReactNode; - variant?: ButtonVariant; + variant?: VariantProp; + color?: ColorPaletteProp; }; export default class IndexNavbarItem extends React.Component { @@ -14,9 +15,9 @@ export default class IndexNavbarItem extends React.Component { super(props); } render(): React.ReactNode { - const { variant, children, href } = this.props; + const { variant, color, children, href } = this.props; return ( - ); diff --git a/sites/app.campground.gg/src/components/index/IndexNavbarPrimary.tsx b/sites/app.campground.gg/src/components/index/IndexNavbarPrimary.tsx new file mode 100644 index 0000000..20d8539 --- /dev/null +++ b/sites/app.campground.gg/src/components/index/IndexNavbarPrimary.tsx @@ -0,0 +1,26 @@ +import { Link } from "@mui/joy"; +import React, { ReactNode } from "react"; +import PrimaryButton from "../PrimaryButton"; + +export type Props = { + children: ReactNode[] | ReactNode; + href: string; + active?: boolean; + icon?: ReactNode; +}; + +export default class IndexNavbarPrimary extends React.Component { + constructor(props: Props) { + super(props); + } + render(): React.ReactNode { + const { children, href } = this.props; + return ( + + + { children } + + + ); + } +} \ No newline at end of file diff --git a/sites/app.campground.gg/src/components/IndexPageWrapper.tsx b/sites/app.campground.gg/src/components/index/IndexPageWrapper.tsx similarity index 53% rename from sites/app.campground.gg/src/components/IndexPageWrapper.tsx rename to sites/app.campground.gg/src/components/index/IndexPageWrapper.tsx index 58433de..f837e8a 100644 --- a/sites/app.campground.gg/src/components/IndexPageWrapper.tsx +++ b/sites/app.campground.gg/src/components/index/IndexPageWrapper.tsx @@ -1,7 +1,7 @@ import React, { ReactNode } from "react"; import IndexNavbar from "./IndexNavbar"; -import { Flex } from "@mantine/core"; import IndexFooter from "./IndexFooter"; +import { Stack } from "@mui/joy"; type Props = { children: ReactNode[] | ReactNode; @@ -16,15 +16,15 @@ export default class IndexPageWrapper extends React.Component { const { children } = this.props; return ( - + - - + + {children} - + - - + + ); } } \ No newline at end of file diff --git a/sites/app.campground.gg/src/css/index.scss b/sites/app.campground.gg/src/css/index.scss index 6992021..d3ba8b1 100644 --- a/sites/app.campground.gg/src/css/index.scss +++ b/sites/app.campground.gg/src/css/index.scss @@ -1,9 +1,5 @@ @use "./functions.scss" as *; -h1, h2, h3, h4, h5, h6 { - font-family: "Quicksand"; -} - .landing-side-padding { @include padding-horizontal(256px); } diff --git a/sites/app.campground.gg/src/routes/Index.tsx b/sites/app.campground.gg/src/routes/Index.tsx index d6fbaf6..84c8b8d 100644 --- a/sites/app.campground.gg/src/routes/Index.tsx +++ b/sites/app.campground.gg/src/routes/Index.tsx @@ -1,8 +1,10 @@ import React from "react"; import { FormattedMessage } from "react-intl"; -import IndexPageWrapper from "../components/IndexPageWrapper"; -import { Button, Group, SimpleGrid, Stack, Text } from "@mantine/core"; +import IndexPageWrapper from "../components/index/IndexPageWrapper"; +// import { Button, Group, SimpleGrid, Stack, Text } from "@mantine/core"; import { IconBrandDebian } from "@tabler/icons-react"; +import { Button, Grid, Link, Stack, Typography } from "@mui/joy"; +import PrimaryButton from "../components/PrimaryButton"; export type Props = { @@ -15,22 +17,34 @@ export default class Index extends React.Component { render() { return ( - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + }> + + + + + + + + ); } diff --git a/sites/app.campground.gg/src/theme.ts b/sites/app.campground.gg/src/theme.ts deleted file mode 100644 index 7e150aa..0000000 --- a/sites/app.campground.gg/src/theme.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { createTheme } from "@mantine/core" - -const theme = createTheme({ - fontFamily: `Nunito Sans, sans-serif`, - primaryColor: "orange", - colors: { - pink: ["#ff2661", "#ff2661", "#ff2661", "#ff2661", "#ff2661", "#ff2661", "#ff2661", "#ff2661", "#ff2661", "#ff2661", ], - red: ["#ff402b", "#ff402b", "#ff402b", "#ff402b", "#ff402b", "#ff402b", "#ff402b", "#ff402b", "#ff402b", "#ff402b", ], - orange: ["#ff5a26", "#ff5a26", "#ff5a26", "#ff5a26", "#ff5a26", "#ff5a26", "#ff5a26", "#ff5a26", "#ff5a26", "#ff5a26"], - green: ["#20eb53", "#20eb53", "#20eb53", "#20eb53", "#20eb53", "#20eb53", "#20eb53", "#20eb53", "#20eb53", "#20eb53", ], - }, - defaultGradient: { - from: "orange", - to: "pink", - deg: 60 - } -}); - -export default theme; \ No newline at end of file diff --git a/sites/app.campground.gg/src/theme/color.ts b/sites/app.campground.gg/src/theme/color.ts new file mode 100644 index 0000000..0208f66 --- /dev/null +++ b/sites/app.campground.gg/src/theme/color.ts @@ -0,0 +1,51 @@ +// From Yoki's code +// Copied by PrettyGoodName, but it was also written by PrettyGoodName +// Not exactly a proprietary code +// Could rewrite in-case it's not in Campground's interest + +const getRedChannel = (value: number) => value >> 16; +const getGreenChannel = (value: number) => (value >> 8) % 0x100; +const getBlueChannel = (value: number) => value % 0x100; +const decimalifyColour = (r: number, g: number, b: number) => (Math.floor(r) << 16) | (Math.floor(g) << 8) | Math.floor(b); + +/** + * Mixes two decimal colours by the given opacity. + * @param c1 First colour to mix in + * @param c2 Second colour to mix in + * @param p2 The floating number that represents percentage of second colour to put in the mix. `1` is `100%` + */ +export function mixColors(c1: number, c2: number, p2: number) { + const p1 = 1 - p2; + + return decimalifyColour( + getRedChannel(c1) * p1 + getRedChannel(c2) * p2, + getGreenChannel(c1) * p1 + getGreenChannel(c2) * p2, + getBlueChannel(c1) * p1 + getBlueChannel(c2) * p2 + ); +} + +/** + * Moves colour more towards grey based on the given %. This is similar to `mixColors`. + * @param c Colour to introduce greyness to + * @param p2 The floating number that represents percentage of grey to put in the mix. `1` is `100%` + */ +export function grayscaleColor(c: number, p2: number) { + const p1 = 1 - p2; + + const red = getRedChannel(c); + const green = getGreenChannel(c); + const blue = getBlueChannel(c); + + // Multiply by %, since blue is naturally darker to our eyes and green is the brightest + const brightness = red * 0.4 + green * 0.6 + blue * 0.2; + const greyness = brightness * p2; + + return decimalifyColour(red * p1 + greyness, green * p1 + greyness, blue * p1 + greyness); +} + +export const mixHexColors = (c1: string, c2: string, p1: number) => getHexString(mixColors(getDecimalValue(c1), getDecimalValue(c2), p1)); + +export const greyscaleHexColor = (c: string, p2: number) => getHexString(grayscaleColor(getDecimalValue(c), p2)); + +export const getDecimalValue = (colour: string) => parseInt(colour.slice(1), 16); +export const getHexString = (colour: number) => `#${colour.toString(16).padStart(6, "0")}`; diff --git a/sites/app.campground.gg/src/theme/dark.ts b/sites/app.campground.gg/src/theme/dark.ts new file mode 100644 index 0000000..85938b7 --- /dev/null +++ b/sites/app.campground.gg/src/theme/dark.ts @@ -0,0 +1,47 @@ +import { ColorSystemOptions } from "@mui/joy/styles/extendTheme"; +import { generateColorScheme } from "./gen"; + +const darkest = "#040409", lightest = "#f5f3ff"; + +const darkColorScheme: ColorSystemOptions = { + palette: { + neutral: { + 950: darkest, + 900: "#0e0b16", + 800: "#151121", + 700: "#181426", + 600: "#1f1b32", + 500: "#231e37", + 400: "#3f405b", + 300: "#78799a", + 200: "#9695b2", + 100: "#dcd8ec", + 50: lightest, + }, + text: { + primary: lightest, + secondary: "#dcd8ec", + tertiary: "#9695b2", + icon: "#78799a", + }, + primary: generateColorScheme("#ff5a26", darkest, lightest), + secondary: generateColorScheme("#ff2661", darkest, lightest), + danger: generateColorScheme("#fe1c56", darkest, lightest), + warning: generateColorScheme("#ff851f", darkest, lightest), + success: generateColorScheme("#2bfa5e", darkest, lightest), + info: generateColorScheme("#6026ff", darkest, lightest), + background: { + popup: "#000000", + body: "#040409", + //backdrop: "#040409", + surface: "#0e0b16", + level1: "#0e0b16", + level2: "#151121", + level3: "#181426", + level4: "#1f1b32", + level5: "#231e37", + } + } +}; + +export default darkColorScheme; \ No newline at end of file diff --git a/sites/app.campground.gg/src/theme/font.ts b/sites/app.campground.gg/src/theme/font.ts new file mode 100644 index 0000000..eb0fc87 --- /dev/null +++ b/sites/app.campground.gg/src/theme/font.ts @@ -0,0 +1,16 @@ +const fallback = [ + `"Montserrat"`, + `"Public Sans"`, + `var(--labs-fontFamily-fallback, var(--labs--apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"))`, +]; + +export const bodyFontFamily = [ + `"Nunito Sans"`, + ...fallback +].join(", "); + +export const displayFontFamily = [ + `"Quicksand"`, + `"Nunito Sans"`, + ...fallback +].join(", "); \ No newline at end of file diff --git a/sites/app.campground.gg/src/theme/gen.ts b/sites/app.campground.gg/src/theme/gen.ts new file mode 100644 index 0000000..4009b93 --- /dev/null +++ b/sites/app.campground.gg/src/theme/gen.ts @@ -0,0 +1,52 @@ +// From Yoki's code +// Copied by PrettyGoodName, but it was also written by PrettyGoodName +// Not exactly a proprietary code +// Could rewrite in-case it's not in Campground's interest + +import { PaletteOptions } from "@mui/joy/styles/types"; +import { greyscaleHexColor, mixHexColors } from "./color"; + +export const generateColorScheme = (typicalColour: string, background: string, counter: string): Partial => ({ + 950: mixHexColors(typicalColour, background, 0.88), + 900: mixHexColors(typicalColour, background, 0.8), + 800: mixHexColors(typicalColour, background, 0.6), + 700: mixHexColors(typicalColour, background, 0.4), + 600: mixHexColors(typicalColour, background, 0.2), + 500: typicalColour, + 400: mixHexColors(typicalColour, counter, 0.2), + 300: mixHexColors(typicalColour, counter, 0.4), + 200: mixHexColors(typicalColour, counter, 0.6), + 100: mixHexColors(typicalColour, counter, 0.8), + // Solid + solidBg: typicalColour, + solidColor: background, + solidHoverBg: mixHexColors(typicalColour, counter, 0.2), + // Plain + plainHoverBg: mixHexColors(typicalColour, background, 0.9), + plainActiveBg: mixHexColors(typicalColour, background, 0.85), + // Outlined + outlinedColor: mixHexColors(typicalColour, counter, 0.5), + outlinedBorder: mixHexColors(typicalColour, background, 0.55), + + outlinedHoverBg: mixHexColors(typicalColour, background, 0.9), + outlinedHoverColor: mixHexColors(typicalColour, counter, 0.6), + outlinedHoverBorder: mixHexColors(typicalColour, background, 0.45), + + outlinedActiveBg: mixHexColors(typicalColour, background, 0.8), + outlinedActiveColor: mixHexColors(typicalColour, counter, 0.7), + outlinedActiveBorder: mixHexColors(typicalColour, background, 0.35), + + outlinedDisabledColor: mixHexColors(greyscaleHexColor(typicalColour, 0.7), background, 0.5), + outlinedDisabledBorder: mixHexColors(typicalColour, background, 0.85), + // Soft + softBg: mixHexColors(typicalColour, background, 0.8), + softColor: mixHexColors(typicalColour, counter, 0.5), + + softHoverBg: mixHexColors(typicalColour, background, 0.7), + softHoverColor: mixHexColors(typicalColour, counter, 0.7), + + softActiveBg: mixHexColors(typicalColour, background, 0.6), + softActiveColor: mixHexColors(typicalColour, counter, 0.8), + // // Transparency + // "sm-opacity": `${typicalColour}55`, +}); \ No newline at end of file diff --git a/sites/app.campground.gg/src/theme/index.ts b/sites/app.campground.gg/src/theme/index.ts new file mode 100644 index 0000000..7ae784f --- /dev/null +++ b/sites/app.campground.gg/src/theme/index.ts @@ -0,0 +1,83 @@ +// import { createTheme } from "@mantine/core" + +import { extendTheme, PaletteVariant } from "@mui/joy"; +import { bodyFontFamily, displayFontFamily } from "./font"; +import lightColorScheme from "./light"; +import darkColorScheme from "./dark"; +import { DefaultPaletteRange } from "@mui/joy/styles/types"; + +declare module "@mui/joy/styles" { + // Add new text levels + interface TypographySystemOverrides { + code: true; + } + interface ListItemButtonPropsVariantOverrides { + indented: true; + } + // Add new text colours + interface PaletteTextOverrides { + code: true; + } + // Add new palette ranges + interface PaletteRangeOverrides { + 950: true; + } + // Add new colours + interface PaletteOptions { + secondary: DefaultPaletteRange & PaletteVariant; + } + // Add new backgrounds + interface PaletteBackgroundOverrides { + // level0: true; + level4: true; + level5: true; + // skeleton0: true; + // skeleton1: true; + } +} + +// Add new colours +declare module "@mui/joy/styles/types/colorSystem" { + interface Palette { + secondary: PaletteRange; + info: PaletteRange; + } + interface ColorPalettePropOverrides { + secondary: true; + info: true; + } +} + +const theme = extendTheme({ + fontFamily: { + body: bodyFontFamily, + display: displayFontFamily + }, + colorSchemes: { + light: lightColorScheme, + dark: darkColorScheme, + }, + components: { + JoyButton: { + styleOverrides: { + root: { + transition: "background 0.3s", + } + }, + } + } + // primaryColor: "orange", + // colors: { + // pink: ["#ff2661", "#ff2661", "#ff2661", "#ff2661", "#ff2661", "#ff2661", "#ff2661", "#ff2661", "#ff2661", "#ff2661", ], + // red: ["#ff402b", "#ff402b", "#ff402b", "#ff402b", "#ff402b", "#ff402b", "#ff402b", "#ff402b", "#ff402b", "#ff402b", ], + // orange: ["#ff5a26", "#ff5a26", "#ff5a26", "#ff5a26", "#ff5a26", "#ff5a26", "#ff5a26", "#ff5a26", "#ff5a26", "#ff5a26"], + // green: ["#20eb53", "#20eb53", "#20eb53", "#20eb53", "#20eb53", "#20eb53", "#20eb53", "#20eb53", "#20eb53", "#20eb53", ], + // }, + // defaultGradient: { + // from: "orange", + // to: "pink", + // deg: 60 + // } +}); + +export default theme; \ No newline at end of file diff --git a/sites/app.campground.gg/src/theme/light.ts b/sites/app.campground.gg/src/theme/light.ts new file mode 100644 index 0000000..70388a7 --- /dev/null +++ b/sites/app.campground.gg/src/theme/light.ts @@ -0,0 +1,12 @@ +import { ColorSystemOptions } from "@mui/joy/styles/extendTheme"; +import { generateColorScheme } from "./gen"; + +const lightColorScheme: ColorSystemOptions = { + palette: { + background: { + + } + } +}; + +export default lightColorScheme; \ No newline at end of file From 2e2ab69a23c560812c4526a4832fa027868ed779 Mon Sep 17 00:00:00 2001 From: IdkGoodName <31628630+IdkGoodName@users.noreply.github.com> Date: Sat, 13 Sep 2025 20:27:45 +1000 Subject: [PATCH 03/14] feat: additional landing pages --- lang/en-US.json | 90 +++++++++- .../public/example-banner.svg | 5 + sites/app.campground.gg/src/App.scss | 6 + sites/app.campground.gg/src/App.tsx | 23 +++ .../src/components/index/BrandLogo.tsx | 16 +- .../src/components/index/DownloadCard.tsx | 37 +++++ .../src/components/index/FeatureCard.tsx | 63 +++++++ .../src/components/index/IndexFooter.tsx | 39 ++--- .../src/components/index/IndexNavbar.tsx | 13 +- .../components/index/IndexNavbarPrimary.tsx | 2 +- .../src/components/index/IndexPageWrapper.tsx | 4 +- .../src/components/index/IndexSection.tsx | 52 ++++++ sites/app.campground.gg/src/css/index.scss | 11 +- .../src/routes/Downloads.tsx | 157 ++++++++++++++++++ .../app.campground.gg/src/routes/Features.tsx | 82 +++++++++ sites/app.campground.gg/src/routes/Index.tsx | 154 +++++++++++++++-- sites/app.campground.gg/src/routes/Soon.tsx | 39 +++++ sites/app.campground.gg/src/theme/gen.ts | 1 + sites/app.campground.gg/src/theme/index.ts | 1 + sites/app.campground.gg/src/theme/light.ts | 1 - 20 files changed, 733 insertions(+), 63 deletions(-) create mode 100644 sites/app.campground.gg/public/example-banner.svg create mode 100644 sites/app.campground.gg/src/components/index/DownloadCard.tsx create mode 100644 sites/app.campground.gg/src/components/index/FeatureCard.tsx create mode 100644 sites/app.campground.gg/src/components/index/IndexSection.tsx create mode 100644 sites/app.campground.gg/src/routes/Downloads.tsx create mode 100644 sites/app.campground.gg/src/routes/Features.tsx create mode 100644 sites/app.campground.gg/src/routes/Soon.tsx diff --git a/lang/en-US.json b/lang/en-US.json index 690fca6..0d90f90 100644 --- a/lang/en-US.json +++ b/lang/en-US.json @@ -9,16 +9,24 @@ "docs": "Docs", "blog": "Blog", "discover": "Discover", - "camps": "Camps", + "campsites": "Campsites", + "campers": "Campers", "instances": "Instances", "socialMedia": "Social media", "resources": "Resources", "openBrowser": "Open in Browser" }, + "underConstruction": { + "title": "Under construction", + "description": "Sorry, this section is still under construction. Come back later!", + "goBackToHome": "Go back to home page" + }, "landing": { "home": "Home", "about": "About", "features": "Features", + "team": "The team", + "brandkit": "Brand kit", "download": { "win": "Download for Windows", "osx": "Download for OSX", @@ -32,7 +40,85 @@ "title": "Gather around the fire, friends", "description": "Campground is the best place for you and your friends to hang out, create communities, and have fun without any hassle!", "download": "Download Campground", - "open": "Open Campground" + "open": "Open Campground", + "bottom": { + "title": "What are you waiting for?", + "description": "Try Campground now, anywhere!" + }, + "campfires": { + "subtitle": "Campfires", + "title": "Organize channels with campfires", + "description": "May also be known as groups or sub-servers, campfires are server-like group of tents/channels with their own icons, banners and roles.", + "learnMore": "Learn more about Campfires" + }, + "profiles": { + "subtitle": "Profiles", + "title": "Highly customizable profiles", + "description": "Create posts and media, discover others, link game and more with Campground's highly customizable profiles.", + "learnMore": "Learn more about Profiles" + }, + "lists": { + "subtitle": "Lists", + "title": "To-do list tents", + "description": "Create list tents (channels) and set up tasks to complete. Organize the tasks, mark them, add notes, create threads and more.", + "learnMore": "Learn more about Lists" + }, + "encryption": { + "subtitle": "Encryption", + "title": "E2EE Private messaging", + "description": "Secure your messages with end-to-end encryption for direct messages. Feel safe with Campground.", + "learnMore": "Learn more about Encryption" + }, + "selfHost": { + "subtitle": "Self-hosting", + "title": "Self-host your campsites", + "description": "Create your own instance and manage YOUR OWN content. No one else, just you and your communities.", + "learnMore": "Learn more about Self-hosting" + }, + "themes": { + "subtitle": "Themes", + "title": "Customize the looks", + "description": "Change the way application looks with highly customizable themes with CSS. Do not like how app looks? Change it!", + "learnMore": "Learn more about Themes" + } + }, + "features": { + "title": "See all of Campgrounds features", + "description": "Campfires? List tents? Calendar tents? Profiles? All here for you to check out and learn!", + "learnMore": "Learn more about {feature}", + "instances": { + "title": "Instances", + "description": "Host your own Campground instances and create campsites on them" + }, + "campfires": { + "title": "Campfires", + "description": "Organize your campsites with campfires." + }, + "encryption": { + "title": "E2E Encryption", + "description": "Learn about direct messages encryption." + }, + "calendarTents": { + "title": "Calendar tents", + "description": "Keep track of events with calendar tents." + }, + "listTents": { + "title": "List tents", + "description": "Create and complete tasks in tents." + }, + "docTents": { + "title": "Document tents", + "description": "Create documents in your tents." + } + }, + "downloads": { + "title": "Get Campground", + "description": "Download Campground on your current device. Everywhere, anywhere; on your phone, on your desktop.", + "wrongDevice": "Wrong device? Scroll down to other downloads.", + "desktop": "Different desktop device?", + "desktopDescription": "Get Campground on any desktop device.", + "mobile": "Or maybe on your phone?", + "mobileDescription": "Make sure everyone can reach you no matter where you are!" }, "languages": { "af-ZA": "Afrikaans", diff --git a/sites/app.campground.gg/public/example-banner.svg b/sites/app.campground.gg/public/example-banner.svg new file mode 100644 index 0000000..c7a36f7 --- /dev/null +++ b/sites/app.campground.gg/public/example-banner.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/sites/app.campground.gg/src/App.scss b/sites/app.campground.gg/src/App.scss index a5ac135..7ac0ea0 100644 --- a/sites/app.campground.gg/src/App.scss +++ b/sites/app.campground.gg/src/App.scss @@ -3,10 +3,16 @@ html, body, #root { width: 100%; height: 100%; + scroll-behavior: smooth; } * { font-family: "Nunito Sans", sans-serif; line-height: 1.6; font-size: 18px; +} + +::selection { + background-color: var(--joy-palette-primary-t-700); + color: white; } \ No newline at end of file diff --git a/sites/app.campground.gg/src/App.tsx b/sites/app.campground.gg/src/App.tsx index b8439e6..4f2082f 100644 --- a/sites/app.campground.gg/src/App.tsx +++ b/sites/app.campground.gg/src/App.tsx @@ -26,6 +26,9 @@ import Index from './routes/Index'; import { CssBaseline, CssVarsProvider, StyledEngineProvider } from '@mui/joy'; import InitColorSchemeScript from '@mui/joy/InitColorSchemeScript'; import theme from "./theme"; +import Downloads from "./routes/Downloads"; +import Soon from "./routes/Soon"; +import Features from "./routes/Features"; function App() { @@ -34,6 +37,26 @@ function App() { path: "/", element: }, + { + path: "/downloads", + element: + }, + { + path: "/blog", + element: + }, + { + path: "/docs/features", + element: + }, + { + path: "/docs", + element: + }, + { + path: "/docs/api", + element: + }, ]); return ( diff --git a/sites/app.campground.gg/src/components/index/BrandLogo.tsx b/sites/app.campground.gg/src/components/index/BrandLogo.tsx index bcdf273..8ad5d6f 100644 --- a/sites/app.campground.gg/src/components/index/BrandLogo.tsx +++ b/sites/app.campground.gg/src/components/index/BrandLogo.tsx @@ -1,4 +1,4 @@ -import { Link, Stack, Typography } from "@mui/joy"; +import { Stack, Typography } from "@mui/joy"; import { DefaultTypographySystem } from "@mui/joy/styles/types"; export type Props = { @@ -18,13 +18,11 @@ export default function BrandLogo({ size, includeText }: Props) { const fz = sizeToFz[size ?? "md"]; return ( - - - - {includeText && - Campground - } - - + + + {includeText && + Campground + } + ) } \ No newline at end of file diff --git a/sites/app.campground.gg/src/components/index/DownloadCard.tsx b/sites/app.campground.gg/src/components/index/DownloadCard.tsx new file mode 100644 index 0000000..a4caa4d --- /dev/null +++ b/sites/app.campground.gg/src/components/index/DownloadCard.tsx @@ -0,0 +1,37 @@ +import { Button, Card, CardContent, ColorPaletteProp, Stack, Typography } from "@mui/joy"; +import { IconDownload } from "@tabler/icons-react"; +import { ReactNode } from "react"; +import { FormattedMessage } from "react-intl"; + +type Props = { + title: string; + description: string; + icon: ReactNode; + color: ColorPaletteProp; + children?: ReactNode[] | ReactNode; + href?: string; + gridColumn?: string; +}; + + +export default function DownloadCard({ title, description, color, icon, href, gridColumn, children }: Props) { + return ( + + + + + + {title} + + + {description} + + + {children || } + + + + ) +} \ No newline at end of file diff --git a/sites/app.campground.gg/src/components/index/FeatureCard.tsx b/sites/app.campground.gg/src/components/index/FeatureCard.tsx new file mode 100644 index 0000000..58e4c1a --- /dev/null +++ b/sites/app.campground.gg/src/components/index/FeatureCard.tsx @@ -0,0 +1,63 @@ +import { AspectRatio, Card, CardContent, CardOverflow, ColorPaletteProp, Link, Stack, Typography } from "@mui/joy"; +import { IconArrowRight } from "@tabler/icons-react"; +import { ReactNode } from "react"; +import { FormattedMessage } from "react-intl"; + +type Props = { + title: string; + description: string; + icon: ReactNode; + href?: string; + imgSrc: string; + color?: ColorPaletteProp; +}; + + +export default function FeatureCard({ title, description, icon, href, imgSrc, color }: Props) { + return ( + + ({ + width: "100%", + height: "100%", + "::before": { + content: "''", + zIndex: 1, + top: 0, + left: 0, + right: 0, + bottom: 0, + border: `solid 2px ${theme.vars.palette[color ?? "primary"][500]}`, + position: "absolute", + borderRadius: theme.vars.radius.md, + maskImage: "linear-gradient(45deg, transparent 0%, black 50%, transparent 100%)", + opacity: 0.5, + } + })} + > + + + + + + + + + + + + + + + + }> + }} /> + + + + + + ) +} \ No newline at end of file diff --git a/sites/app.campground.gg/src/components/index/IndexFooter.tsx b/sites/app.campground.gg/src/components/index/IndexFooter.tsx index e7a960f..e0c583d 100644 --- a/sites/app.campground.gg/src/components/index/IndexFooter.tsx +++ b/sites/app.campground.gg/src/components/index/IndexFooter.tsx @@ -3,7 +3,7 @@ import BrandLogo from "./BrandLogo"; import IndexFooterItem from "./IndexFooterItem"; import IndexFooterSection from "./IndexFooterSection"; import { FormattedMessage } from "react-intl"; -import { IconBrandBluesky, IconBrandDiscord, IconBrandGithub, IconBrandX } from "@tabler/icons-react"; +import { IconAffiliateFilled, IconBrandBluesky, IconBrandDiscord, IconBrandGithub, IconBrandX, IconCamper, IconCampfireFilled, IconChristmasTreeFilled, IconUsersGroup } from "@tabler/icons-react"; import { Grid, Stack } from "@mui/joy"; export type Props = { @@ -15,9 +15,9 @@ export default class IndexFooter extends React.Component { } render() { return ( - + - + } href="https://github.com/Project-Campground">GitHub } href="https://bsky.app/profile/campground.gg">Bluesky @@ -38,36 +38,23 @@ export default class IndexFooter extends React.Component { - - - + + }> + - - + }> + - - - - + }> - - - - + }> + - - - - - - - - - - + }> + diff --git a/sites/app.campground.gg/src/components/index/IndexNavbar.tsx b/sites/app.campground.gg/src/components/index/IndexNavbar.tsx index 5875435..65e03d3 100644 --- a/sites/app.campground.gg/src/components/index/IndexNavbar.tsx +++ b/sites/app.campground.gg/src/components/index/IndexNavbar.tsx @@ -17,13 +17,10 @@ export default class IndexNavbar extends React.Component { return ( - - + + - - - - + @@ -32,12 +29,12 @@ export default class IndexNavbar extends React.Component { - + - + diff --git a/sites/app.campground.gg/src/components/index/IndexNavbarPrimary.tsx b/sites/app.campground.gg/src/components/index/IndexNavbarPrimary.tsx index 20d8539..97cc7d4 100644 --- a/sites/app.campground.gg/src/components/index/IndexNavbarPrimary.tsx +++ b/sites/app.campground.gg/src/components/index/IndexNavbarPrimary.tsx @@ -16,7 +16,7 @@ export default class IndexNavbarPrimary extends React.Component { render(): React.ReactNode { const { children, href } = this.props; return ( - + { children } diff --git a/sites/app.campground.gg/src/components/index/IndexPageWrapper.tsx b/sites/app.campground.gg/src/components/index/IndexPageWrapper.tsx index f837e8a..7438aa6 100644 --- a/sites/app.campground.gg/src/components/index/IndexPageWrapper.tsx +++ b/sites/app.campground.gg/src/components/index/IndexPageWrapper.tsx @@ -18,8 +18,8 @@ export default class IndexPageWrapper extends React.Component { return ( - - + + {children} diff --git a/sites/app.campground.gg/src/components/index/IndexSection.tsx b/sites/app.campground.gg/src/components/index/IndexSection.tsx new file mode 100644 index 0000000..fd59876 --- /dev/null +++ b/sites/app.campground.gg/src/components/index/IndexSection.tsx @@ -0,0 +1,52 @@ +import { Grid, Link, Stack, Typography } from "@mui/joy"; +import { IconArrowRight } from "@tabler/icons-react"; +import React, { ReactNode } from "react"; +import { FormattedMessage } from "react-intl"; +import PrimaryButton from "../PrimaryButton"; + +type Props = { + subtitle: string; + title: string; + description: string; + icon: ReactNode[] | ReactNode; + learnMore: string; + learnMoreHref: string; +}; + +export default class IndexSection extends React.Component { + constructor(props: Props) { + super(props); + } + + render() { + const { subtitle, title, description, learnMore, learnMoreHref, icon } = this.props; + + return ( + + + + + {icon} + + + + + + + + + + + + + + + }> + + + + + + ) + } +} \ No newline at end of file diff --git a/sites/app.campground.gg/src/css/index.scss b/sites/app.campground.gg/src/css/index.scss index d3ba8b1..b5da980 100644 --- a/sites/app.campground.gg/src/css/index.scss +++ b/sites/app.campground.gg/src/css/index.scss @@ -1,10 +1,12 @@ @use "./functions.scss" as *; +$landingSidePadding: 256px; + .landing-side-padding { - @include padding-horizontal(256px); + @include padding-horizontal($landingSidePadding); } .landing-side-padding-nav { - @include padding-horizontal(256px - 24.75px); + @include padding-horizontal($landingSidePadding - 24.75px); } .landing-extreme-top { padding-top: 128px + 64px; @@ -31,6 +33,7 @@ .BrandLogo.img { width: 56px; height: 56px; + user-select: none; &.xs { width: 36px; height: 36px; @@ -60,4 +63,8 @@ &.top-motto-text { margin-bottom: 24px; } +} + +.FeatureCard.img { + border-radius: 8px; } \ No newline at end of file diff --git a/sites/app.campground.gg/src/routes/Downloads.tsx b/sites/app.campground.gg/src/routes/Downloads.tsx new file mode 100644 index 0000000..848116f --- /dev/null +++ b/sites/app.campground.gg/src/routes/Downloads.tsx @@ -0,0 +1,157 @@ +import React from "react"; +import { FormattedMessage } from "react-intl"; +import IndexPageWrapper from "../components/index/IndexPageWrapper"; +// import { Button, Group, SimpleGrid, Stack, Text } from "@mantine/core"; +import { IconBrandAndroid, IconBrandApple, IconBrandDebian, IconBrandGooglePlay, IconBrandWindows, IconDownload, IconFeather } from "@tabler/icons-react"; +import { Grid, Link, Option, Select, Stack, Typography } from "@mui/joy"; +import PrimaryButton from "../components/PrimaryButton"; +import DownloadCard from "../components/index/DownloadCard"; + +export type Props = { + +}; + +export default class Downloads extends React.Component { + constructor(props: Props) { + super(props); + } + render() { + return ( + + + + + + + + + + + + + + + + + + + + }> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + } + href="/downloads" + /> + } + href="/downloads" + /> + } + href="/downloads" + /> + } + href="/downloads" + gridColumn="1 / 4" + > + + + + + + + + + + + + + + + + + + + + + + } + href="/downloads" + /> + } + href="/downloads" + /> + } + href="/downloads" + /> + + + + + + + ); + } +} \ No newline at end of file diff --git a/sites/app.campground.gg/src/routes/Features.tsx b/sites/app.campground.gg/src/routes/Features.tsx new file mode 100644 index 0000000..c39fefc --- /dev/null +++ b/sites/app.campground.gg/src/routes/Features.tsx @@ -0,0 +1,82 @@ +import React from "react"; +import { FormattedMessage } from "react-intl"; +import IndexPageWrapper from "../components/index/IndexPageWrapper"; +// import { Button, Group, SimpleGrid, Stack, Text } from "@mantine/core"; +import { IconCalendarFilled, IconCampfireFilled, IconCheckbox, IconFileTextFilled, IconLockFilled, IconServer } from "@tabler/icons-react"; +import { Box, Grid, Stack, Typography } from "@mui/joy" +import FeatureCard from "../components/index/FeatureCard"; + +export type Props = { + +}; + +export default class Features extends React.Component { + constructor(props: Props) { + super(props); + } + render() { + return ( + + + + + + + + + + + + + } + href="/docs/features/campfires" + imgSrc="/example-banner.svg" + /> + } + href="/docs/features/instances" + imgSrc="/example-banner.svg" + color="warning" + /> + } + href="/docs/features/encryption" + imgSrc="/example-banner.svg" + color="info" + /> + } + href="/docs/features/calendar-tents" + imgSrc="/example-banner.svg" + color="danger" + /> + } + href="/docs/features/list-tents" + imgSrc="/example-banner.svg" + color="success" + /> + } + href="/docs/features/doc-tents" + imgSrc="/example-banner.svg" + color="secondary" + /> + + + ); + } +} \ No newline at end of file diff --git a/sites/app.campground.gg/src/routes/Index.tsx b/sites/app.campground.gg/src/routes/Index.tsx index 84c8b8d..23edca9 100644 --- a/sites/app.campground.gg/src/routes/Index.tsx +++ b/sites/app.campground.gg/src/routes/Index.tsx @@ -2,9 +2,10 @@ import React from "react"; import { FormattedMessage } from "react-intl"; import IndexPageWrapper from "../components/index/IndexPageWrapper"; // import { Button, Group, SimpleGrid, Stack, Text } from "@mantine/core"; -import { IconBrandDebian } from "@tabler/icons-react"; -import { Button, Grid, Link, Stack, Typography } from "@mui/joy"; +import { IconBrandDebian, IconCamper, IconCampfire, IconCheckbox, IconLock, IconPalette, IconServer } from "@tabler/icons-react"; +import { Box, Button, Grid, Link, Sheet, Stack, Typography } from "@mui/joy"; import PrimaryButton from "../components/PrimaryButton"; +import IndexSection from "../components/index/IndexSection"; export type Props = { @@ -17,9 +18,10 @@ export default class Index extends React.Component { render() { return ( + {/* Top motto of the Index */} - + @@ -32,20 +34,148 @@ export default class Index extends React.Component { - - - }> - - - - + + + + }> + + + + + + Incorrect operating system? Click here to check out downloads page! + {/* Features in the Index */} + + + + + Example content + + + + } + title="home.campfires.title" + description="home.campfires.description" + learnMore="home.campfires.learnMore" + learnMoreHref="/" + /> + } + title="home.selfHost.title" + description="home.selfHost.description" + learnMore="home.selfHost.learnMore" + learnMoreHref="/" + /> + } + title="home.encryption.title" + description="home.encryption.description" + learnMore="home.encryption.learnMore" + learnMoreHref="/" + /> + } + title="home.profiles.title" + description="home.profiles.description" + learnMore="home.profiles.learnMore" + learnMoreHref="/" + /> + } + title="home.lists.title" + description="home.lists.description" + learnMore="home.lists.learnMore" + learnMoreHref="/" + /> + } + title="home.themes.title" + description="home.themes.description" + learnMore="home.themes.learnMore" + learnMoreHref="/" + /> + + ); } +} + +class IndexBottomSection extends React.Component { + constructor(props: {}) { + super(props); + } + + render() { + return ( + + ({ + background: `linear-gradient(90deg, ${theme.vars.palette.primary[500]}, ${theme.vars.palette.secondary[500]})`, + position: "absolute", + top: 0, + left: -10, + bottom: 0, + right: -10, + rotate: "1.5deg", + "::before": { + position: "absolute", + content: "''", + top: 0, + bottom: 0, + left: 0, + right: 0, + background: `linear-gradient(0deg, ${theme.vars.palette.info[500]}, transparent, ${theme.vars.palette.warning[500]})`, + opacity: 0.25, + }, + })} + > + + + + + + + + + + + + + + + + + + + + ) + } } \ No newline at end of file diff --git a/sites/app.campground.gg/src/routes/Soon.tsx b/sites/app.campground.gg/src/routes/Soon.tsx new file mode 100644 index 0000000..1a8a887 --- /dev/null +++ b/sites/app.campground.gg/src/routes/Soon.tsx @@ -0,0 +1,39 @@ +import React from "react"; +import { FormattedMessage } from "react-intl"; +import IndexPageWrapper from "../components/index/IndexPageWrapper"; +// import { Button, Group, SimpleGrid, Stack, Text } from "@mantine/core"; +import { Link, Stack, Typography } from "@mui/joy"; +import { IconDoorExit, IconMoodSadFilled } from "@tabler/icons-react"; +import PrimaryButton from "../components/PrimaryButton"; + +export type Props = { + +}; + +export default class Soon extends React.Component { + constructor(props: Props) { + super(props); + } + render() { + return ( + + + + + + + + + + + + + }> + + + + + + ); + } +} \ No newline at end of file diff --git a/sites/app.campground.gg/src/theme/gen.ts b/sites/app.campground.gg/src/theme/gen.ts index 4009b93..9a61702 100644 --- a/sites/app.campground.gg/src/theme/gen.ts +++ b/sites/app.campground.gg/src/theme/gen.ts @@ -12,6 +12,7 @@ export const generateColorScheme = (typicalColour: string, background: string, c 800: mixHexColors(typicalColour, background, 0.6), 700: mixHexColors(typicalColour, background, 0.4), 600: mixHexColors(typicalColour, background, 0.2), + "t-700": `${typicalColour}cc`, 500: typicalColour, 400: mixHexColors(typicalColour, counter, 0.2), 300: mixHexColors(typicalColour, counter, 0.4), diff --git a/sites/app.campground.gg/src/theme/index.ts b/sites/app.campground.gg/src/theme/index.ts index 7ae784f..9e0de3d 100644 --- a/sites/app.campground.gg/src/theme/index.ts +++ b/sites/app.campground.gg/src/theme/index.ts @@ -21,6 +21,7 @@ declare module "@mui/joy/styles" { // Add new palette ranges interface PaletteRangeOverrides { 950: true; + ["t-700"]: true; } // Add new colours interface PaletteOptions { diff --git a/sites/app.campground.gg/src/theme/light.ts b/sites/app.campground.gg/src/theme/light.ts index 70388a7..218a015 100644 --- a/sites/app.campground.gg/src/theme/light.ts +++ b/sites/app.campground.gg/src/theme/light.ts @@ -1,5 +1,4 @@ import { ColorSystemOptions } from "@mui/joy/styles/extendTheme"; -import { generateColorScheme } from "./gen"; const lightColorScheme: ColorSystemOptions = { palette: { From 9c5208fba4ea79898719d5161edf8da37a0d6c24 Mon Sep 17 00:00:00 2001 From: IdkGoodName <31628630+IdkGoodName@users.noreply.github.com> Date: Wed, 17 Sep 2025 11:47:21 +1000 Subject: [PATCH 04/14] feat: login and register pages, forms, 404 default page --- lang/en-US.json | 31 +++++- sites/app.campground.gg/src/App.scss | 2 +- sites/app.campground.gg/src/App.tsx | 20 ++++ .../src/components/{index => }/BrandLogo.tsx | 0 .../src/components/PrimaryButton.tsx | 6 +- .../src/components/form/AbstractFormField.tsx | 17 +++ .../src/components/form/Form.tsx | 89 +++++++++++++++ .../src/components/form/FormFieldText.tsx | 58 ++++++++++ .../src/components/form/FormFieldWrapper.tsx | 23 ++++ .../src/components/form/FormSection.tsx | 28 +++++ .../src/components/form/forms.tsx | 43 ++++++++ .../components/index/IndexBareboneWrapper.tsx | 29 +++++ .../src/components/index/IndexFooter.tsx | 2 +- .../src/components/index/IndexNavbar.tsx | 58 +++++----- .../src/components/index/IndexPageWrapper.tsx | 15 +-- .../src/components/signin/SigninNavbar.tsx | 26 +++++ .../src/components/signin/SigninWrapper.tsx | 82 ++++++++++++++ sites/app.campground.gg/src/routes/Index.tsx | 12 +- sites/app.campground.gg/src/routes/Login.tsx | 85 ++++++++++++++ .../app.campground.gg/src/routes/NotFound.tsx | 39 +++++++ .../app.campground.gg/src/routes/Register.tsx | 104 ++++++++++++++++++ .../src/routes/ResetPassword.tsx | 81 ++++++++++++++ sites/app.campground.gg/src/routes/Soon.tsx | 4 +- sites/app.campground.gg/src/theme/dark.ts | 2 + sites/app.campground.gg/src/theme/gen.ts | 2 +- sites/app.campground.gg/src/theme/index.ts | 4 +- 26 files changed, 805 insertions(+), 57 deletions(-) rename sites/app.campground.gg/src/components/{index => }/BrandLogo.tsx (100%) create mode 100644 sites/app.campground.gg/src/components/form/AbstractFormField.tsx create mode 100644 sites/app.campground.gg/src/components/form/Form.tsx create mode 100644 sites/app.campground.gg/src/components/form/FormFieldText.tsx create mode 100644 sites/app.campground.gg/src/components/form/FormFieldWrapper.tsx create mode 100644 sites/app.campground.gg/src/components/form/FormSection.tsx create mode 100644 sites/app.campground.gg/src/components/form/forms.tsx create mode 100644 sites/app.campground.gg/src/components/index/IndexBareboneWrapper.tsx create mode 100644 sites/app.campground.gg/src/components/signin/SigninNavbar.tsx create mode 100644 sites/app.campground.gg/src/components/signin/SigninWrapper.tsx create mode 100644 sites/app.campground.gg/src/routes/Login.tsx create mode 100644 sites/app.campground.gg/src/routes/NotFound.tsx create mode 100644 sites/app.campground.gg/src/routes/Register.tsx create mode 100644 sites/app.campground.gg/src/routes/ResetPassword.tsx diff --git a/lang/en-US.json b/lang/en-US.json index 0d90f90..7c79757 100644 --- a/lang/en-US.json +++ b/lang/en-US.json @@ -1,7 +1,5 @@ { "global": { - "login": "Sign in", - "register": "Sign up", "support": "Support", "download": "Download", "themeToggle": "Toggle color scheme", @@ -16,9 +14,32 @@ "resources": "Resources", "openBrowser": "Open in Browser" }, - "underConstruction": { - "title": "Under construction", - "description": "Sorry, this section is still under construction. Come back later!", + "info": { + "username": "Username", + "tagline": "Tag", + "taglineOrEmail": "Tag or Email", + "email": "Email", + "password": "Password", + "confirmPassword": "Confirm password" + }, + "form": { + "login": "Sign in", + "register": "Sign up", + "noAccount": "Don't have an account? Register", + "hasAccount": "Already have an account? Login", + "resetPasswordTitle": "Reset password", + "resetPassword": "Forgot your password? Change it", + "submit": "Submit" + }, + "placeholder": { + "underConstruction": { + "title": "Under Construction", + "description": "Sorry, this section is still under construction. Come back later!" + }, + "notFound": { + "title": "404 Not Found", + "description": "This page could not be found." + }, "goBackToHome": "Go back to home page" }, "landing": { diff --git a/sites/app.campground.gg/src/App.scss b/sites/app.campground.gg/src/App.scss index 7ac0ea0..755105c 100644 --- a/sites/app.campground.gg/src/App.scss +++ b/sites/app.campground.gg/src/App.scss @@ -13,6 +13,6 @@ html, body, #root { } ::selection { - background-color: var(--joy-palette-primary-t-700); + background-color: var(--joy-palette-primary-t-500); color: white; } \ No newline at end of file diff --git a/sites/app.campground.gg/src/App.tsx b/sites/app.campground.gg/src/App.tsx index 4f2082f..ec5d284 100644 --- a/sites/app.campground.gg/src/App.tsx +++ b/sites/app.campground.gg/src/App.tsx @@ -29,10 +29,18 @@ import theme from "./theme"; import Downloads from "./routes/Downloads"; import Soon from "./routes/Soon"; import Features from "./routes/Features"; +import Login from "./routes/Login"; +import Register from "./routes/Register"; +import NotFound from "./routes/NotFound"; +import ResetPassword from "./routes/ResetPassword"; function App() { const router = createBrowserRouter([ + { + path: "*", + element: + }, { path: "/", element: @@ -41,6 +49,18 @@ function App() { path: "/downloads", element: }, + { + path: "/login", + element: + }, + { + path: "/register", + element: + }, + { + path: "/reset-password", + element: + }, { path: "/blog", element: diff --git a/sites/app.campground.gg/src/components/index/BrandLogo.tsx b/sites/app.campground.gg/src/components/BrandLogo.tsx similarity index 100% rename from sites/app.campground.gg/src/components/index/BrandLogo.tsx rename to sites/app.campground.gg/src/components/BrandLogo.tsx diff --git a/sites/app.campground.gg/src/components/PrimaryButton.tsx b/sites/app.campground.gg/src/components/PrimaryButton.tsx index 776e388..ec8ee36 100644 --- a/sites/app.campground.gg/src/components/PrimaryButton.tsx +++ b/sites/app.campground.gg/src/components/PrimaryButton.tsx @@ -1,8 +1,8 @@ import { Button, styled } from "@mui/joy"; -const PrimaryButton = styled(Button)(({ theme }) => ({ - background: `linear-gradient(30deg, ${theme.vars.palette.primary[500]}, ${theme.vars.palette.secondary[500]})`, - boxShadow: `0 0 5px ${theme.vars.palette.primary[500]}`, +const PrimaryButton = styled(Button)(({ disabled, theme }) => ({ + background: disabled ? `linear-gradient(30deg, ${theme.vars.palette.neutral[300]}, ${theme.vars.palette.neutral[500]})` : `linear-gradient(30deg, ${theme.vars.palette.primary[500]}, ${theme.vars.palette.secondary[500]})`, + boxShadow: disabled ? `0 0 5px ${theme.vars.palette.neutral[400]}` : `0 0 5px ${theme.vars.palette.primary[500]}`, "::after": { content: '""', zIndex: 1, diff --git a/sites/app.campground.gg/src/components/form/AbstractFormField.tsx b/sites/app.campground.gg/src/components/form/AbstractFormField.tsx new file mode 100644 index 0000000..8d88c9d --- /dev/null +++ b/sites/app.campground.gg/src/components/form/AbstractFormField.tsx @@ -0,0 +1,17 @@ +import React from "react"; +import { AbstractAnyFormField, FormFieldProps, FormFieldType } from "./forms"; + +export default abstract class AbstractFormField, TState> extends React.Component { + constructor(props: TProps) { + super(props); + } + + public abstract get isValid(): boolean; + + public abstract render(): React.ReactNode; + + protected onChange(value: TValue) { + return this.props.onChange && this.props.onChange(this as unknown as AbstractAnyFormField, value); + } + +} \ No newline at end of file diff --git a/sites/app.campground.gg/src/components/form/Form.tsx b/sites/app.campground.gg/src/components/form/Form.tsx new file mode 100644 index 0000000..67b779f --- /dev/null +++ b/sites/app.campground.gg/src/components/form/Form.tsx @@ -0,0 +1,89 @@ +import React, { FormEvent, ReactNode } from "react"; +import { AnyFormField, FormSectionProps, AnyFormFieldProps } from "./forms"; +import { Stack, Typography } from "@mui/joy"; +import PrimaryButton from "../PrimaryButton"; +import { FormattedMessage } from "react-intl"; +import FormSection from "./FormSection"; + +export type FormProps = { + header?: ReactNode | ReactNode[]; + sections: FormSectionProps[]; + submitText?: string; + children?: ReactNode[] | ReactNode; + onSubmit: (ev: FormEvent, fieldValues: Record) => Promise | void; +}; +type FormState = { + fieldValues: Record; + fieldRequirementFilled: Record; +}; + +export default class Form extends React.Component { + constructor(props: FormProps) { + super(props); + this.state = { + fieldValues: {}, + fieldRequirementFilled: Object.fromEntries( + props + .sections + .flatMap(x => x.fields) + .map(x => [x.id, !x.required || !!x.defaultValue])) + }; + } + + public onButtonSubmit(ev: FormEvent) { + ev.preventDefault(); + return this.props.onSubmit(ev, this.state.fieldValues); + } + + private onFieldChange(props: AnyFormFieldProps, field: AnyFormField, value: any): Promise | void { + this.setState(({ fieldValues, fieldRequirementFilled }) => ({ + fieldValues: { + ...fieldValues, + [props.id]: value + }, + fieldRequirementFilled: { + ...fieldRequirementFilled, + [props.id]: field.isValid + } + })); + + return props.onChange && props.onChange(field, value); + } + + private get isButtonDisabled(): boolean { + return ( + !Object.values(this.state.fieldRequirementFilled).every(x => x) + ); + } + + public render(): ReactNode[] | ReactNode { + const { header, sections, submitText, children } = this.props; + + return ( +
+ + {header && + {header} + } + {/* Sections */} + + {sections.map(section => + + )} + + {/* Form footer */} + + + + + { children } + + +
+ ); + } +} \ No newline at end of file diff --git a/sites/app.campground.gg/src/components/form/FormFieldText.tsx b/sites/app.campground.gg/src/components/form/FormFieldText.tsx new file mode 100644 index 0000000..05f91f5 --- /dev/null +++ b/sites/app.campground.gg/src/components/form/FormFieldText.tsx @@ -0,0 +1,58 @@ +import { ChangeEvent, HTMLInputTypeAttribute, ReactNode } from "react"; +import AbstractFormField from "./AbstractFormField"; +import { FormFieldDecoratorProps, FormFieldProps } from "./forms"; +import { Input } from "@mui/joy"; + +export interface FormFieldTextProps extends FormFieldProps<"text", string>, FormFieldDecoratorProps { + inputType?: HTMLInputTypeAttribute; + placeholder?: string; + format?: RegExp; +} + +type State = { + value: string; +}; + +export default class FormFieldText extends AbstractFormField<"text", string, FormFieldTextProps, State> { + constructor(props: FormFieldTextProps) { + super(props); + this.state = { value: "" }; + } + + public override get isValid(): boolean { + return this.isNotEmptyOrRequired && this.isFormatValid; + } + + private get isNotEmptyOrRequired(): boolean { + return !this.props.required || this.state.value.length > 0; + } + + private get isFormatValid(): boolean { + // Special thanks to De Morgan for solving this mess + // !this.props.format || !!this.props.format!.exec(this.state.value) + return !(this.props.format && !this.props.format!.exec(this.state.value)); + } + + private onInputChange(ev: ChangeEvent) { + const { value } = ev.target; + + this.setState({ value }, () => this.onChange(ev.target.value)); + } + + public override render(): ReactNode { + const { startDecorator, endDecorator, defaultValue, placeholder, inputType } = this.props; + const { isFormatValid, state: { value } } = this; + + return ( + 0 && !isFormatValid} + /> + ); + } +} \ No newline at end of file diff --git a/sites/app.campground.gg/src/components/form/FormFieldWrapper.tsx b/sites/app.campground.gg/src/components/form/FormFieldWrapper.tsx new file mode 100644 index 0000000..f315f8a --- /dev/null +++ b/sites/app.campground.gg/src/components/form/FormFieldWrapper.tsx @@ -0,0 +1,23 @@ +import { FormControl, FormLabel } from "@mui/joy"; +import Form from "./Form"; +import { AnyFormField, AnyFormFieldComponent, AnyFormFieldProps } from "./forms"; + +type Props = { + FieldComponent: AnyFormFieldComponent; + onChange: (props: TProps, field: AnyFormField, value: TValue) => Promise | void; + binding: Form; + props: TProps; +}; + +export default function FormFieldWrapper({ FieldComponent, onChange, binding, props }: Props) { + return ( + + {props.header && {props.header}} + + {props.footer} + + ) +} \ No newline at end of file diff --git a/sites/app.campground.gg/src/components/form/FormSection.tsx b/sites/app.campground.gg/src/components/form/FormSection.tsx new file mode 100644 index 0000000..fa01c72 --- /dev/null +++ b/sites/app.campground.gg/src/components/form/FormSection.tsx @@ -0,0 +1,28 @@ +import { Stack, Typography } from "@mui/joy"; +import { AnyFormField, AnyFormFieldProps, fieldTypeToComponent, FormSectionProps } from "./forms"; +import FormFieldWrapper from "./FormFieldWrapper"; +import Form from "./Form"; + +type Props = { + section: FormSectionProps; + fieldBinding: Form; + onFieldChange: (props: AnyFormFieldProps, field: AnyFormField, value: any) => Promise | void; +} + +export default function FormSection({ onFieldChange, fieldBinding, section: { header, fields } }: Props) { + return ( + + {header} + + {fields.map(field => + + )} + + + ) +} \ No newline at end of file diff --git a/sites/app.campground.gg/src/components/form/forms.tsx b/sites/app.campground.gg/src/components/form/forms.tsx new file mode 100644 index 0000000..26fd350 --- /dev/null +++ b/sites/app.campground.gg/src/components/form/forms.tsx @@ -0,0 +1,43 @@ +import { ReactNode } from "react"; +import AbstractFormField from "./AbstractFormField"; +import FormFieldText, { FormFieldTextProps } from "./FormFieldText"; + +export type FormSectionProps = { + header?: ReactNode | ReactNode[]; + fields: AnyFormFieldProps[]; +}; + +export type FormFieldType = "text"; + +export type FormFieldTypeToProps = { + text: FormFieldTextProps; +}; + +export type AnyFormFieldProps = FormFieldTextProps; + +export type AnyFormFieldComponent = new(props: FormFieldProps) => AbstractAnyFormField; + +export type AbstractAnyFormField = AbstractFormField, any>; + +export type AnyFormField = FormFieldText; + +export const fieldTypeToComponent = { + text: FormFieldText, +}; + +export interface FormFieldProps { + type: TType; + id: string; + + header?: ReactNode[] | ReactNode; + footer?: ReactNode[] | ReactNode; + required?: boolean; + defaultValue?: TValue; + + onChange?: (field: AbstractFormField, any>, value: TValue) => Promise | void; +} + +export interface FormFieldDecoratorProps { + startDecorator?: ReactNode[] | ReactNode; + endDecorator?: ReactNode[] | ReactNode; +} \ No newline at end of file diff --git a/sites/app.campground.gg/src/components/index/IndexBareboneWrapper.tsx b/sites/app.campground.gg/src/components/index/IndexBareboneWrapper.tsx new file mode 100644 index 0000000..7b2e22b --- /dev/null +++ b/sites/app.campground.gg/src/components/index/IndexBareboneWrapper.tsx @@ -0,0 +1,29 @@ +import React, { ReactNode } from "react"; +import IndexNavbar from "./IndexNavbar"; +import { Stack } from "@mui/joy"; +import { SxProps } from "@mui/joy/styles/types"; + +type Props = { + sx?: SxProps; + bodySx?: SxProps; + children: ReactNode[] | ReactNode; +}; + +export default class IndexBareboneWrapper extends React.Component { + constructor(props: Props) { + super(props); + } + + render() { + const { sx, bodySx, children } = this.props; + + return ( + + + + {children} + + + ); + } +} \ No newline at end of file diff --git a/sites/app.campground.gg/src/components/index/IndexFooter.tsx b/sites/app.campground.gg/src/components/index/IndexFooter.tsx index e0c583d..344af37 100644 --- a/sites/app.campground.gg/src/components/index/IndexFooter.tsx +++ b/sites/app.campground.gg/src/components/index/IndexFooter.tsx @@ -1,5 +1,5 @@ import React from "react"; -import BrandLogo from "./BrandLogo"; +import BrandLogo from "../BrandLogo"; import IndexFooterItem from "./IndexFooterItem"; import IndexFooterSection from "./IndexFooterSection"; import { FormattedMessage } from "react-intl"; diff --git a/sites/app.campground.gg/src/components/index/IndexNavbar.tsx b/sites/app.campground.gg/src/components/index/IndexNavbar.tsx index 65e03d3..460ab4a 100644 --- a/sites/app.campground.gg/src/components/index/IndexNavbar.tsx +++ b/sites/app.campground.gg/src/components/index/IndexNavbar.tsx @@ -1,8 +1,8 @@ import React from "react"; -import BrandLogo from "./BrandLogo"; +import BrandLogo from "../BrandLogo"; import IndexNavbarItem from "./IndexNavbarItem"; import { FormattedMessage } from "react-intl"; -import { Link, Stack } from "@mui/joy"; +import { Box, Link, Stack } from "@mui/joy"; import IndexNavbarPrimary from "./IndexNavbarPrimary"; export type Props = { @@ -15,33 +15,35 @@ export default class IndexNavbar extends React.Component { } render() { return ( - - - - - - - - - - - - - - - - - + ({ position: "sticky", top: 0, zIndex: 20, backgroundColor: theme.vars.palette.background.transparent })}> + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + ); } } \ No newline at end of file diff --git a/sites/app.campground.gg/src/components/index/IndexPageWrapper.tsx b/sites/app.campground.gg/src/components/index/IndexPageWrapper.tsx index 7438aa6..dd4bbe0 100644 --- a/sites/app.campground.gg/src/components/index/IndexPageWrapper.tsx +++ b/sites/app.campground.gg/src/components/index/IndexPageWrapper.tsx @@ -1,7 +1,7 @@ import React, { ReactNode } from "react"; -import IndexNavbar from "./IndexNavbar"; import IndexFooter from "./IndexFooter"; import { Stack } from "@mui/joy"; +import IndexBareboneWrapper from "./IndexBareboneWrapper"; type Props = { children: ReactNode[] | ReactNode; @@ -16,15 +16,12 @@ export default class IndexPageWrapper extends React.Component { const { children } = this.props; return ( - - - - - {children} - - + + + {children} - + + ); } } \ No newline at end of file diff --git a/sites/app.campground.gg/src/components/signin/SigninNavbar.tsx b/sites/app.campground.gg/src/components/signin/SigninNavbar.tsx new file mode 100644 index 0000000..5759123 --- /dev/null +++ b/sites/app.campground.gg/src/components/signin/SigninNavbar.tsx @@ -0,0 +1,26 @@ +import React from "react"; +import BrandLogo from "../BrandLogo"; +import { Box, Link, Stack } from "@mui/joy"; + +export type Props = { + page: string; +}; + +export default class SigninNavbar extends React.Component { + constructor(props: Props) { + super(props); + } + render() { + return ( + + + + + + + + + + ); + } +} \ No newline at end of file diff --git a/sites/app.campground.gg/src/components/signin/SigninWrapper.tsx b/sites/app.campground.gg/src/components/signin/SigninWrapper.tsx new file mode 100644 index 0000000..eb88dcd --- /dev/null +++ b/sites/app.campground.gg/src/components/signin/SigninWrapper.tsx @@ -0,0 +1,82 @@ +import React, { ReactNode } from "react"; +import { Box, Sheet, Stack, Typography } from "@mui/joy"; +import { SxProps } from "@mui/joy/styles/types"; +import { FormattedMessage } from "react-intl"; +import SigninNavbar from "./SigninNavbar"; + +type Props = { + header: string; + sx?: SxProps; + bodySx?: SxProps; + children: ReactNode[] | ReactNode; +}; + +export default class SigninWrapper extends React.Component { + constructor(props: Props) { + super(props); + } + + render() { + const { header, sx, bodySx, children } = this.props; + + return ( + + + + ({ + position: "absolute", + top: 0, + left: 0, + right: 0, + bottom: 0, + background: `linear-gradient(to bottom, ${theme.vars.palette.info[950]}, ${theme.vars.palette.info[300]})`, + overflow: "hidden", + zIndex: -1, + })}> + ({ + background: `linear-gradient(to left, ${theme.vars.palette.background.body}, ${theme.vars.palette.background.level1})`, + position: "absolute", + content: "''", + zIndex: 2, + top: -1000, + left: -1000, + right: "40%", + bottom: -500, + rotate: "6deg", + // borderRadius: "300% 50%", + mask: [ + `radial-gradient(514.3px at calc(100% - 690px) 50%,#000 100.8%,#0000 101%) 0 calc(50% - 460px)/100% 920px`, + `radial-gradient(519.3px at calc(100% + 470px) 50%,#0000 100.8%,#000 101%) calc(100% - 225px) 50%/100% 920px repeat-y`, + ].join(",") + })}> + + + + + + ({ backgroundColor: theme.vars.palette.background.level1, minWidth: 650, borderRadius: theme.vars.radius.lg, boxShadow: theme.vars.shadow.xl })}> + + + + + + + + {/*
*/} + {children} + {/*
*/} +
+
+
+
+
+ {/* + + + + */} +
+
+ ); + } +} \ No newline at end of file diff --git a/sites/app.campground.gg/src/routes/Index.tsx b/sites/app.campground.gg/src/routes/Index.tsx index 23edca9..b512b37 100644 --- a/sites/app.campground.gg/src/routes/Index.tsx +++ b/sites/app.campground.gg/src/routes/Index.tsx @@ -65,7 +65,7 @@ export default class Index extends React.Component { title="home.campfires.title" description="home.campfires.description" learnMore="home.campfires.learnMore" - learnMoreHref="/" + learnMoreHref="/docs/features/campfires" /> { title="home.selfHost.title" description="home.selfHost.description" learnMore="home.selfHost.learnMore" - learnMoreHref="/" + learnMoreHref="/docs/features/instances" /> { title="home.encryption.title" description="home.encryption.description" learnMore="home.encryption.learnMore" - learnMoreHref="/" + learnMoreHref="/docs/features/encryption" /> { title="home.profiles.title" description="home.profiles.description" learnMore="home.profiles.learnMore" - learnMoreHref="/" + learnMoreHref="/docs/features/profiles" /> { title="home.lists.title" description="home.lists.description" learnMore="home.lists.learnMore" - learnMoreHref="/" + learnMoreHref="/docs/features/list-tents" /> { title="home.themes.title" description="home.themes.description" learnMore="home.themes.learnMore" - learnMoreHref="/" + learnMoreHref="/docs/features/themes" />
diff --git a/sites/app.campground.gg/src/routes/Login.tsx b/sites/app.campground.gg/src/routes/Login.tsx new file mode 100644 index 0000000..ecbb8a5 --- /dev/null +++ b/sites/app.campground.gg/src/routes/Login.tsx @@ -0,0 +1,85 @@ +import React, { FormEvent } from "react"; +// import { Button, Group, SimpleGrid, Stack, Text } from "@mantine/core"; +import SigninWrapper from "../components/signin/SigninWrapper"; +import { FormattedMessage } from "react-intl"; +import Form from "../components/form/Form"; +import { Link } from "@mui/joy"; + +export type Props = { + +}; + +export default class Login extends React.Component { + constructor(props: Props) { + super(props); + } + onSubmit(event: FormEvent, fieldValues: Record) { + event.preventDefault(); + + const details = { + email: fieldValues.email, + password: fieldValues.password, + } + + console.log(details); + } + render() { + return ( + +
, + format: /^(?:([A-Za-z0-9._%+-]+)@((?:[A-Za-z0-9-]+[.])+[A-Za-z]{2,})|[A-Za-z0-9$_.-]+)$/, + required: true + }, + { + type: "text", + id: "password", + inputType: "password", + placeholder: "Password here", + header: , + footer: + + , + required: true + } + ] + } + ]} + onSubmit={this.onSubmit} + submitText="form.login" + > + + + + + {/* + + + Email + + + + Password + + Forgot your password? + + + + + + + Don't have an account? Sign up + + */} +
+ ); + } +} \ No newline at end of file diff --git a/sites/app.campground.gg/src/routes/NotFound.tsx b/sites/app.campground.gg/src/routes/NotFound.tsx new file mode 100644 index 0000000..e977a00 --- /dev/null +++ b/sites/app.campground.gg/src/routes/NotFound.tsx @@ -0,0 +1,39 @@ +import React from "react"; +import { FormattedMessage } from "react-intl"; +import IndexPageWrapper from "../components/index/IndexPageWrapper"; +// import { Button, Group, SimpleGrid, Stack, Text } from "@mantine/core"; +import { Link, Stack, Typography } from "@mui/joy"; +import { IconDoorExit, IconMoodAngryFilled } from "@tabler/icons-react"; +import PrimaryButton from "../components/PrimaryButton"; + +export type Props = { + +}; + +export default class NotFound extends React.Component { + constructor(props: Props) { + super(props); + } + render() { + return ( + + + + + + + + + + + + + }> + + + + + + ); + } +} \ No newline at end of file diff --git a/sites/app.campground.gg/src/routes/Register.tsx b/sites/app.campground.gg/src/routes/Register.tsx new file mode 100644 index 0000000..5858704 --- /dev/null +++ b/sites/app.campground.gg/src/routes/Register.tsx @@ -0,0 +1,104 @@ +import React, { ChangeEvent } from "react"; +// import { Button, Group, SimpleGrid, Stack, Text } from "@mantine/core"; +import { Link, Stack, Typography } from "@mui/joy"; +import { IconAt } from "@tabler/icons-react"; +import SigninWrapper from "../components/signin/SigninWrapper"; +import { FormattedMessage } from "react-intl"; +import Form from "../components/form/Form"; + +export type Props = { + +}; +type PasswordState = { + password: string; + confirmPassword: string; +} +export type State = PasswordState & { + wrongConfirmPassword: boolean; +}; + +export default class Register extends React.Component { + constructor(props: Props) { + super(props); + this.state = { wrongConfirmPassword: false, password: "", confirmPassword: "" }; + } + onSubmit(event: React.FormEvent, fieldValues: Record) { + event.preventDefault(); + + console.log(fieldValues); + } + onPasswordInputChange(property: "password" | "confirmPassword", e: ChangeEvent) { + const { password, confirmPassword } = this.state; + + const newState: Partial = { password, confirmPassword, [property]: e.target.value }; + + this.setState({ ...newState, wrongConfirmPassword: newState.password !== newState.confirmPassword } as State); + } + render() { + return ( + +
, + required: true + }, + { + type: "text", + id: "tagline", + placeholder: "Tag_Here", + header: , + format: /^([A-Za-z0-9$_.-]+)$/, + startDecorator: + + + + + + , + required: true + }, + { + type: "text", + id: "email", + inputType: "email", + placeholder: "example@example.com", + header: , + format: /^([A-Za-z0-9._%+-]+)@((?:[A-Za-z0-9-]+[.])+[A-Za-z]{2,})$/, + required: true + }, + { + type: "text", + id: "password", + inputType: "password", + placeholder: "Password here", + header: , + required: true + }, + { + type: "text", + id: "confirmPassword", + inputType: "password", + placeholder: "Password here", + header: , + required: true + } + ] + } + ]} + onSubmit={this.onSubmit} + submitText="form.register" + > + + + + +
+ ); + } +} \ No newline at end of file diff --git a/sites/app.campground.gg/src/routes/ResetPassword.tsx b/sites/app.campground.gg/src/routes/ResetPassword.tsx new file mode 100644 index 0000000..ad0ef9b --- /dev/null +++ b/sites/app.campground.gg/src/routes/ResetPassword.tsx @@ -0,0 +1,81 @@ +import React, { ChangeEvent } from "react"; +// import { Button, Group, SimpleGrid, Stack, Text } from "@mantine/core"; +import { Link } from "@mui/joy"; +import SigninWrapper from "../components/signin/SigninWrapper"; +import { FormattedMessage } from "react-intl"; +import Form from "../components/form/Form"; + +export type Props = { + +}; +type PasswordState = { + password: string; + confirmPassword: string; +} +export type State = PasswordState & { + wrongConfirmPassword: boolean; +}; + +export default class ResetPassword extends React.Component { + constructor(props: Props) { + super(props); + this.state = { wrongConfirmPassword: false, password: "", confirmPassword: "" }; + } + onSubmit(event: React.FormEvent, fieldValues: Record) { + event.preventDefault(); + + console.log(fieldValues); + } + onPasswordInputChange(property: "password" | "confirmPassword", e: ChangeEvent) { + const { password, confirmPassword } = this.state; + + const newState: Partial = { password, confirmPassword, [property]: e.target.value }; + + this.setState({ ...newState, wrongConfirmPassword: newState.password !== newState.confirmPassword } as State); + } + render() { + return ( + +
, + format: /^([A-Za-z0-9._%+-]+)@((?:[A-Za-z0-9-]+[.])+[A-Za-z]{2,})$/, + required: true + }, + { + type: "text", + id: "password", + inputType: "password", + placeholder: "Password here", + header: , + required: true + }, + { + type: "text", + id: "confirmPassword", + inputType: "password", + placeholder: "Password here", + header: , + required: true + } + ] + } + ]} + onSubmit={this.onSubmit} + submitText="form.resetPasswordTitle" + > + + + + +
+ ); + } +} \ No newline at end of file diff --git a/sites/app.campground.gg/src/routes/Soon.tsx b/sites/app.campground.gg/src/routes/Soon.tsx index 1a8a887..948493d 100644 --- a/sites/app.campground.gg/src/routes/Soon.tsx +++ b/sites/app.campground.gg/src/routes/Soon.tsx @@ -22,10 +22,10 @@ export default class Soon extends React.Component { - + - + }> diff --git a/sites/app.campground.gg/src/theme/dark.ts b/sites/app.campground.gg/src/theme/dark.ts index 85938b7..fa97563 100644 --- a/sites/app.campground.gg/src/theme/dark.ts +++ b/sites/app.campground.gg/src/theme/dark.ts @@ -6,6 +6,7 @@ const darkest = "#040409", lightest = "#f5f3ff"; const darkColorScheme: ColorSystemOptions = { palette: { neutral: { + "t-950": `${darkest}cc`, 950: darkest, 900: "#0e0b16", 800: "#151121", @@ -31,6 +32,7 @@ const darkColorScheme: ColorSystemOptions = { success: generateColorScheme("#2bfa5e", darkest, lightest), info: generateColorScheme("#6026ff", darkest, lightest), background: { + transparent: "#040409dd", popup: "#000000", body: "#040409", //backdrop: "#040409", diff --git a/sites/app.campground.gg/src/theme/gen.ts b/sites/app.campground.gg/src/theme/gen.ts index 9a61702..decf04e 100644 --- a/sites/app.campground.gg/src/theme/gen.ts +++ b/sites/app.campground.gg/src/theme/gen.ts @@ -12,7 +12,7 @@ export const generateColorScheme = (typicalColour: string, background: string, c 800: mixHexColors(typicalColour, background, 0.6), 700: mixHexColors(typicalColour, background, 0.4), 600: mixHexColors(typicalColour, background, 0.2), - "t-700": `${typicalColour}cc`, + "t-500": `${typicalColour}cc`, 500: typicalColour, 400: mixHexColors(typicalColour, counter, 0.2), 300: mixHexColors(typicalColour, counter, 0.4), diff --git a/sites/app.campground.gg/src/theme/index.ts b/sites/app.campground.gg/src/theme/index.ts index 9e0de3d..310e940 100644 --- a/sites/app.campground.gg/src/theme/index.ts +++ b/sites/app.campground.gg/src/theme/index.ts @@ -21,7 +21,8 @@ declare module "@mui/joy/styles" { // Add new palette ranges interface PaletteRangeOverrides { 950: true; - ["t-700"]: true; + ["t-950"]: true; + ["t-500"]: true; } // Add new colours interface PaletteOptions { @@ -29,6 +30,7 @@ declare module "@mui/joy/styles" { } // Add new backgrounds interface PaletteBackgroundOverrides { + transparent: true; // level0: true; level4: true; level5: true; From e929d8d9c0d7c6432e8c950531938c366db3f518 Mon Sep 17 00:00:00 2001 From: IdkGoodName <31628630+IdkGoodName@users.noreply.github.com> Date: Wed, 17 Sep 2025 13:47:21 +1000 Subject: [PATCH 05/14] feat: rename Index to Landing, fix sticky landing element --- sites/app.campground.gg/src/App.scss | 1 - sites/app.campground.gg/src/App.tsx | 8 +-- .../src/components/index/IndexFooter.tsx | 64 ------------------- ...Wrapper.tsx => LandingBareboneWrapper.tsx} | 10 +-- .../src/components/index/LandingFooter.tsx | 64 +++++++++++++++++++ ...exFooterItem.tsx => LandingFooterItem.tsx} | 2 +- ...erSection.tsx => LandingFooterSection.tsx} | 2 +- .../{IndexNavbar.tsx => LandingNavbar.tsx} | 30 ++++----- ...exNavbarItem.tsx => LandingNavbarItem.tsx} | 2 +- ...arPrimary.tsx => LandingNavbarPrimary.tsx} | 2 +- ...PageWrapper.tsx => LandingPageWrapper.tsx} | 12 ++-- .../{IndexSection.tsx => LandingSection.tsx} | 2 +- .../app.campground.gg/src/routes/NotFound.tsx | 6 +- sites/app.campground.gg/src/routes/Soon.tsx | 6 +- .../src/routes/{ => landing}/Downloads.tsx | 10 +-- .../src/routes/{ => landing}/Features.tsx | 8 +-- .../{Index.tsx => landing/LandingIndex.tsx} | 33 +++++----- 17 files changed, 131 insertions(+), 131 deletions(-) delete mode 100644 sites/app.campground.gg/src/components/index/IndexFooter.tsx rename sites/app.campground.gg/src/components/index/{IndexBareboneWrapper.tsx => LandingBareboneWrapper.tsx} (69%) create mode 100644 sites/app.campground.gg/src/components/index/LandingFooter.tsx rename sites/app.campground.gg/src/components/index/{IndexFooterItem.tsx => LandingFooterItem.tsx} (88%) rename sites/app.campground.gg/src/components/index/{IndexFooterSection.tsx => LandingFooterSection.tsx} (90%) rename sites/app.campground.gg/src/components/index/{IndexNavbar.tsx => LandingNavbar.tsx} (64%) rename sites/app.campground.gg/src/components/index/{IndexNavbarItem.tsx => LandingNavbarItem.tsx} (90%) rename sites/app.campground.gg/src/components/index/{IndexNavbarPrimary.tsx => LandingNavbarPrimary.tsx} (89%) rename sites/app.campground.gg/src/components/index/{IndexPageWrapper.tsx => LandingPageWrapper.tsx} (61%) rename sites/app.campground.gg/src/components/index/{IndexSection.tsx => LandingSection.tsx} (96%) rename sites/app.campground.gg/src/routes/{ => landing}/Downloads.tsx (97%) rename sites/app.campground.gg/src/routes/{ => landing}/Features.tsx (94%) rename sites/app.campground.gg/src/routes/{Index.tsx => landing/LandingIndex.tsx} (91%) diff --git a/sites/app.campground.gg/src/App.scss b/sites/app.campground.gg/src/App.scss index 755105c..d1ad742 100644 --- a/sites/app.campground.gg/src/App.scss +++ b/sites/app.campground.gg/src/App.scss @@ -2,7 +2,6 @@ html, body, #root { width: 100%; - height: 100%; scroll-behavior: smooth; } diff --git a/sites/app.campground.gg/src/App.tsx b/sites/app.campground.gg/src/App.tsx index ec5d284..f4b8e6c 100644 --- a/sites/app.campground.gg/src/App.tsx +++ b/sites/app.campground.gg/src/App.tsx @@ -22,13 +22,13 @@ import '@mantine/tiptap/styles.css'; import '@mantine/dropzone/styles.css'; import { IntlProvider } from './i18n'; import { SessionProvider } from './session'; -import Index from './routes/Index'; +import LandingIndex from './routes/landing/LandingIndex'; import { CssBaseline, CssVarsProvider, StyledEngineProvider } from '@mui/joy'; import InitColorSchemeScript from '@mui/joy/InitColorSchemeScript'; import theme from "./theme"; -import Downloads from "./routes/Downloads"; +import Downloads from "./routes/landing/Downloads"; import Soon from "./routes/Soon"; -import Features from "./routes/Features"; +import Features from "./routes/landing/Features"; import Login from "./routes/Login"; import Register from "./routes/Register"; import NotFound from "./routes/NotFound"; @@ -43,7 +43,7 @@ function App() { }, { path: "/", - element: + element: }, { path: "/downloads", diff --git a/sites/app.campground.gg/src/components/index/IndexFooter.tsx b/sites/app.campground.gg/src/components/index/IndexFooter.tsx deleted file mode 100644 index 344af37..0000000 --- a/sites/app.campground.gg/src/components/index/IndexFooter.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import React from "react"; -import BrandLogo from "../BrandLogo"; -import IndexFooterItem from "./IndexFooterItem"; -import IndexFooterSection from "./IndexFooterSection"; -import { FormattedMessage } from "react-intl"; -import { IconAffiliateFilled, IconBrandBluesky, IconBrandDiscord, IconBrandGithub, IconBrandX, IconCamper, IconCampfireFilled, IconChristmasTreeFilled, IconUsersGroup } from "@tabler/icons-react"; -import { Grid, Stack } from "@mui/joy"; - -export type Props = { -}; - -export default class IndexFooter extends React.Component { - constructor(props: Props) { - super(props); - } - render() { - return ( - - - - - } href="https://github.com/Project-Campground">GitHub - } href="https://bsky.app/profile/campground.gg">Bluesky - } href="https://discord.com/invite/jasJ97UXDM">Discord - } href="https://x.com/teamcampground">X/Twitter - - - - - - - - - - - - - - - - - }> - - - }> - - - - - }> - - - }> - - - }> - - - - - - ); - } -} \ No newline at end of file diff --git a/sites/app.campground.gg/src/components/index/IndexBareboneWrapper.tsx b/sites/app.campground.gg/src/components/index/LandingBareboneWrapper.tsx similarity index 69% rename from sites/app.campground.gg/src/components/index/IndexBareboneWrapper.tsx rename to sites/app.campground.gg/src/components/index/LandingBareboneWrapper.tsx index 7b2e22b..bd5a76b 100644 --- a/sites/app.campground.gg/src/components/index/IndexBareboneWrapper.tsx +++ b/sites/app.campground.gg/src/components/index/LandingBareboneWrapper.tsx @@ -1,5 +1,5 @@ import React, { ReactNode } from "react"; -import IndexNavbar from "./IndexNavbar"; +import LandingNavbar from "./LandingNavbar"; import { Stack } from "@mui/joy"; import { SxProps } from "@mui/joy/styles/types"; @@ -9,7 +9,7 @@ type Props = { children: ReactNode[] | ReactNode; }; -export default class IndexBareboneWrapper extends React.Component { +export default class LandingBareboneWrapper extends React.Component { constructor(props: Props) { super(props); } @@ -18,9 +18,9 @@ export default class IndexBareboneWrapper extends React.Component { const { sx, bodySx, children } = this.props; return ( - - - + + + {children} diff --git a/sites/app.campground.gg/src/components/index/LandingFooter.tsx b/sites/app.campground.gg/src/components/index/LandingFooter.tsx new file mode 100644 index 0000000..844e750 --- /dev/null +++ b/sites/app.campground.gg/src/components/index/LandingFooter.tsx @@ -0,0 +1,64 @@ +import React from "react"; +import BrandLogo from "../BrandLogo"; +import LandingFooterItem from "./LandingFooterItem"; +import LandingFooterSection from "./LandingFooterSection"; +import { FormattedMessage } from "react-intl"; +import { IconAffiliateFilled, IconBrandBluesky, IconBrandDiscord, IconBrandGithub, IconBrandX, IconCamper, IconCampfireFilled, IconChristmasTreeFilled, IconUsersGroup } from "@tabler/icons-react"; +import { Grid, Stack } from "@mui/joy"; + +export type Props = { +}; + +export default class LandingFooter extends React.Component { + constructor(props: Props) { + super(props); + } + render() { + return ( + + + + + } href="https://github.com/Project-Campground">GitHub + } href="https://bsky.app/profile/campground.gg">Bluesky + } href="https://discord.com/invite/jasJ97UXDM">Discord + } href="https://x.com/teamcampground">X/Twitter + + + + + + + + + + + + + + + + + }> + + + }> + + + + + }> + + + }> + + + }> + + + + + + ); + } +} \ No newline at end of file diff --git a/sites/app.campground.gg/src/components/index/IndexFooterItem.tsx b/sites/app.campground.gg/src/components/index/LandingFooterItem.tsx similarity index 88% rename from sites/app.campground.gg/src/components/index/IndexFooterItem.tsx rename to sites/app.campground.gg/src/components/index/LandingFooterItem.tsx index a056835..40ffc74 100644 --- a/sites/app.campground.gg/src/components/index/IndexFooterItem.tsx +++ b/sites/app.campground.gg/src/components/index/LandingFooterItem.tsx @@ -7,7 +7,7 @@ export type Props = { href?: string; }; -export default class IndexFooterItem extends React.Component { +export default class LandingFooterItem extends React.Component { constructor(props: Props) { super(props); } diff --git a/sites/app.campground.gg/src/components/index/IndexFooterSection.tsx b/sites/app.campground.gg/src/components/index/LandingFooterSection.tsx similarity index 90% rename from sites/app.campground.gg/src/components/index/IndexFooterSection.tsx rename to sites/app.campground.gg/src/components/index/LandingFooterSection.tsx index 18a6863..89d6235 100644 --- a/sites/app.campground.gg/src/components/index/IndexFooterSection.tsx +++ b/sites/app.campground.gg/src/components/index/LandingFooterSection.tsx @@ -7,7 +7,7 @@ export type Props = { children?: ReactNode[]; }; -export default class IndexFooterSection extends React.Component { +export default class LandingFooterSection extends React.Component { constructor(props: Props) { super(props); } diff --git a/sites/app.campground.gg/src/components/index/IndexNavbar.tsx b/sites/app.campground.gg/src/components/index/LandingNavbar.tsx similarity index 64% rename from sites/app.campground.gg/src/components/index/IndexNavbar.tsx rename to sites/app.campground.gg/src/components/index/LandingNavbar.tsx index 460ab4a..ac6d295 100644 --- a/sites/app.campground.gg/src/components/index/IndexNavbar.tsx +++ b/sites/app.campground.gg/src/components/index/LandingNavbar.tsx @@ -1,15 +1,15 @@ import React from "react"; import BrandLogo from "../BrandLogo"; -import IndexNavbarItem from "./IndexNavbarItem"; +import LandingNavbarItem from "./LandingNavbarItem"; import { FormattedMessage } from "react-intl"; import { Box, Link, Stack } from "@mui/joy"; -import IndexNavbarPrimary from "./IndexNavbarPrimary"; +import LandingNavbarPrimary from "./LandingNavbarPrimary"; export type Props = { page: string; }; -export default class IndexNavbar extends React.Component { +export default class LandingNavbar extends React.Component { constructor(props: Props) { super(props); } @@ -21,26 +21,26 @@ export default class IndexNavbar extends React.Component { - + - - + + - - + + - - + + - + - + - - + + - + diff --git a/sites/app.campground.gg/src/components/index/IndexNavbarItem.tsx b/sites/app.campground.gg/src/components/index/LandingNavbarItem.tsx similarity index 90% rename from sites/app.campground.gg/src/components/index/IndexNavbarItem.tsx rename to sites/app.campground.gg/src/components/index/LandingNavbarItem.tsx index a027712..6172631 100644 --- a/sites/app.campground.gg/src/components/index/IndexNavbarItem.tsx +++ b/sites/app.campground.gg/src/components/index/LandingNavbarItem.tsx @@ -10,7 +10,7 @@ export type Props = { color?: ColorPaletteProp; }; -export default class IndexNavbarItem extends React.Component { +export default class LandingNavbarItem extends React.Component { constructor(props: Props) { super(props); } diff --git a/sites/app.campground.gg/src/components/index/IndexNavbarPrimary.tsx b/sites/app.campground.gg/src/components/index/LandingNavbarPrimary.tsx similarity index 89% rename from sites/app.campground.gg/src/components/index/IndexNavbarPrimary.tsx rename to sites/app.campground.gg/src/components/index/LandingNavbarPrimary.tsx index 97cc7d4..074d009 100644 --- a/sites/app.campground.gg/src/components/index/IndexNavbarPrimary.tsx +++ b/sites/app.campground.gg/src/components/index/LandingNavbarPrimary.tsx @@ -9,7 +9,7 @@ export type Props = { icon?: ReactNode; }; -export default class IndexNavbarPrimary extends React.Component { +export default class LandingNavbarPrimary extends React.Component { constructor(props: Props) { super(props); } diff --git a/sites/app.campground.gg/src/components/index/IndexPageWrapper.tsx b/sites/app.campground.gg/src/components/index/LandingPageWrapper.tsx similarity index 61% rename from sites/app.campground.gg/src/components/index/IndexPageWrapper.tsx rename to sites/app.campground.gg/src/components/index/LandingPageWrapper.tsx index dd4bbe0..dee5b74 100644 --- a/sites/app.campground.gg/src/components/index/IndexPageWrapper.tsx +++ b/sites/app.campground.gg/src/components/index/LandingPageWrapper.tsx @@ -1,13 +1,13 @@ import React, { ReactNode } from "react"; -import IndexFooter from "./IndexFooter"; +import LandingFooter from "./LandingFooter"; import { Stack } from "@mui/joy"; -import IndexBareboneWrapper from "./IndexBareboneWrapper"; +import LandingBareboneWrapper from "./LandingBareboneWrapper"; type Props = { children: ReactNode[] | ReactNode; }; -export default class IndexPageWrapper extends React.Component { +export default class LandingPageWrapper extends React.Component { constructor(props: Props) { super(props); } @@ -16,12 +16,12 @@ export default class IndexPageWrapper extends React.Component { const { children } = this.props; return ( - + {children} - - + + ); } } \ No newline at end of file diff --git a/sites/app.campground.gg/src/components/index/IndexSection.tsx b/sites/app.campground.gg/src/components/index/LandingSection.tsx similarity index 96% rename from sites/app.campground.gg/src/components/index/IndexSection.tsx rename to sites/app.campground.gg/src/components/index/LandingSection.tsx index fd59876..bccc872 100644 --- a/sites/app.campground.gg/src/components/index/IndexSection.tsx +++ b/sites/app.campground.gg/src/components/index/LandingSection.tsx @@ -13,7 +13,7 @@ type Props = { learnMoreHref: string; }; -export default class IndexSection extends React.Component { +export default class LandingSection extends React.Component { constructor(props: Props) { super(props); } diff --git a/sites/app.campground.gg/src/routes/NotFound.tsx b/sites/app.campground.gg/src/routes/NotFound.tsx index e977a00..9c1192e 100644 --- a/sites/app.campground.gg/src/routes/NotFound.tsx +++ b/sites/app.campground.gg/src/routes/NotFound.tsx @@ -1,6 +1,6 @@ import React from "react"; import { FormattedMessage } from "react-intl"; -import IndexPageWrapper from "../components/index/IndexPageWrapper"; +import LandingPageWrapper from "../components/index/LandingPageWrapper"; // import { Button, Group, SimpleGrid, Stack, Text } from "@mantine/core"; import { Link, Stack, Typography } from "@mui/joy"; import { IconDoorExit, IconMoodAngryFilled } from "@tabler/icons-react"; @@ -16,7 +16,7 @@ export default class NotFound extends React.Component { } render() { return ( - + @@ -33,7 +33,7 @@ export default class NotFound extends React.Component {
- + ); } } \ No newline at end of file diff --git a/sites/app.campground.gg/src/routes/Soon.tsx b/sites/app.campground.gg/src/routes/Soon.tsx index 948493d..234a8ca 100644 --- a/sites/app.campground.gg/src/routes/Soon.tsx +++ b/sites/app.campground.gg/src/routes/Soon.tsx @@ -1,6 +1,6 @@ import React from "react"; import { FormattedMessage } from "react-intl"; -import IndexPageWrapper from "../components/index/IndexPageWrapper"; +import LandingPageWrapper from "../components/index/LandingPageWrapper"; // import { Button, Group, SimpleGrid, Stack, Text } from "@mantine/core"; import { Link, Stack, Typography } from "@mui/joy"; import { IconDoorExit, IconMoodSadFilled } from "@tabler/icons-react"; @@ -16,7 +16,7 @@ export default class Soon extends React.Component { } render() { return ( - + @@ -33,7 +33,7 @@ export default class Soon extends React.Component { - + ); } } \ No newline at end of file diff --git a/sites/app.campground.gg/src/routes/Downloads.tsx b/sites/app.campground.gg/src/routes/landing/Downloads.tsx similarity index 97% rename from sites/app.campground.gg/src/routes/Downloads.tsx rename to sites/app.campground.gg/src/routes/landing/Downloads.tsx index 848116f..14acd54 100644 --- a/sites/app.campground.gg/src/routes/Downloads.tsx +++ b/sites/app.campground.gg/src/routes/landing/Downloads.tsx @@ -1,11 +1,11 @@ import React from "react"; import { FormattedMessage } from "react-intl"; -import IndexPageWrapper from "../components/index/IndexPageWrapper"; +import LandingPageWrapper from "../../components/index/LandingPageWrapper"; // import { Button, Group, SimpleGrid, Stack, Text } from "@mantine/core"; import { IconBrandAndroid, IconBrandApple, IconBrandDebian, IconBrandGooglePlay, IconBrandWindows, IconDownload, IconFeather } from "@tabler/icons-react"; import { Grid, Link, Option, Select, Stack, Typography } from "@mui/joy"; -import PrimaryButton from "../components/PrimaryButton"; -import DownloadCard from "../components/index/DownloadCard"; +import PrimaryButton from "../../components/PrimaryButton"; +import DownloadCard from "../../components/index/DownloadCard"; export type Props = { @@ -17,7 +17,7 @@ export default class Downloads extends React.Component { } render() { return ( - + @@ -151,7 +151,7 @@ export default class Downloads extends React.Component { - + ); } } \ No newline at end of file diff --git a/sites/app.campground.gg/src/routes/Features.tsx b/sites/app.campground.gg/src/routes/landing/Features.tsx similarity index 94% rename from sites/app.campground.gg/src/routes/Features.tsx rename to sites/app.campground.gg/src/routes/landing/Features.tsx index c39fefc..a5c9637 100644 --- a/sites/app.campground.gg/src/routes/Features.tsx +++ b/sites/app.campground.gg/src/routes/landing/Features.tsx @@ -1,10 +1,10 @@ import React from "react"; import { FormattedMessage } from "react-intl"; -import IndexPageWrapper from "../components/index/IndexPageWrapper"; +import LandingPageWrapper from "../../components/index/LandingPageWrapper"; // import { Button, Group, SimpleGrid, Stack, Text } from "@mantine/core"; import { IconCalendarFilled, IconCampfireFilled, IconCheckbox, IconFileTextFilled, IconLockFilled, IconServer } from "@tabler/icons-react"; import { Box, Grid, Stack, Typography } from "@mui/joy" -import FeatureCard from "../components/index/FeatureCard"; +import FeatureCard from "../../components/index/FeatureCard"; export type Props = { @@ -16,7 +16,7 @@ export default class Features extends React.Component { } render() { return ( - + @@ -76,7 +76,7 @@ export default class Features extends React.Component { color="secondary" /> - + ); } } \ No newline at end of file diff --git a/sites/app.campground.gg/src/routes/Index.tsx b/sites/app.campground.gg/src/routes/landing/LandingIndex.tsx similarity index 91% rename from sites/app.campground.gg/src/routes/Index.tsx rename to sites/app.campground.gg/src/routes/landing/LandingIndex.tsx index b512b37..e886164 100644 --- a/sites/app.campground.gg/src/routes/Index.tsx +++ b/sites/app.campground.gg/src/routes/landing/LandingIndex.tsx @@ -1,23 +1,23 @@ import React from "react"; import { FormattedMessage } from "react-intl"; -import IndexPageWrapper from "../components/index/IndexPageWrapper"; +import LandingPageWrapper from "../../components/index/LandingPageWrapper"; // import { Button, Group, SimpleGrid, Stack, Text } from "@mantine/core"; import { IconBrandDebian, IconCamper, IconCampfire, IconCheckbox, IconLock, IconPalette, IconServer } from "@tabler/icons-react"; import { Box, Button, Grid, Link, Sheet, Stack, Typography } from "@mui/joy"; -import PrimaryButton from "../components/PrimaryButton"; -import IndexSection from "../components/index/IndexSection"; +import PrimaryButton from "../../components/PrimaryButton"; +import LandingSection from "../../components/index/LandingSection"; export type Props = { }; -export default class Index extends React.Component { +export default class LandingIndex extends React.Component { constructor(props: Props) { super(props); } render() { return ( - + {/* Top motto of the Index */} @@ -53,13 +53,13 @@ export default class Index extends React.Component { {/* Features in the Index */} - + Example content - } title="home.campfires.title" @@ -67,7 +67,7 @@ export default class Index extends React.Component { learnMore="home.campfires.learnMore" learnMoreHref="/docs/features/campfires" /> - } title="home.selfHost.title" @@ -75,7 +75,7 @@ export default class Index extends React.Component { learnMore="home.selfHost.learnMore" learnMoreHref="/docs/features/instances" /> - } title="home.encryption.title" @@ -83,7 +83,7 @@ export default class Index extends React.Component { learnMore="home.encryption.learnMore" learnMoreHref="/docs/features/encryption" /> - } title="home.profiles.title" @@ -91,7 +91,7 @@ export default class Index extends React.Component { learnMore="home.profiles.learnMore" learnMoreHref="/docs/features/profiles" /> - } title="home.lists.title" @@ -99,7 +99,7 @@ export default class Index extends React.Component { learnMore="home.lists.learnMore" learnMoreHref="/docs/features/list-tents" /> - } title="home.themes.title" @@ -109,7 +109,7 @@ export default class Index extends React.Component { /> - + ); } } @@ -129,16 +129,17 @@ class IndexBottomSection extends React.Component { sx={{ background: "transparent", px: 20, - py: 20, + py: 25, + overflow: "hidden" }} > ({ background: `linear-gradient(90deg, ${theme.vars.palette.primary[500]}, ${theme.vars.palette.secondary[500]})`, position: "absolute", - top: 0, + top: 25, left: -10, - bottom: 0, + bottom: 25, right: -10, rotate: "1.5deg", "::before": { From 09fadc4821646cf7d03f75b3d85cbca036501c0b Mon Sep 17 00:00:00 2001 From: IdkGoodName <31628630+IdkGoodName@users.noreply.github.com> Date: Sat, 20 Sep 2025 19:39:44 +1000 Subject: [PATCH 06/14] feat: landing page improvements --- .../src/components/ObservabilityDisplay.tsx | 73 ++++++++++++++ .../src/components/index/LandingSection.tsx | 5 +- .../index/sticky/LandingStickyCampfire.tsx | 77 +++++++++++++++ .../index/sticky/LandingStickyEncryption.tsx | 96 +++++++++++++++++++ .../index/sticky/LandingStickyLists.tsx | 89 +++++++++++++++++ .../index/sticky/LandingStickyProfile.tsx | 46 +++++++++ .../index/sticky/LandingStickySelfHosts.tsx | 50 ++++++++++ .../index/sticky/LandingStickyThemes.tsx | 54 +++++++++++ .../src/components/index/sticky/animations.ts | 13 +++ .../src/routes/landing/LandingIndex.tsx | 32 +++++-- sites/app.campground.gg/src/theme/gen.ts | 2 + sites/app.campground.gg/src/theme/index.ts | 14 +-- 12 files changed, 530 insertions(+), 21 deletions(-) create mode 100644 sites/app.campground.gg/src/components/ObservabilityDisplay.tsx create mode 100644 sites/app.campground.gg/src/components/index/sticky/LandingStickyCampfire.tsx create mode 100644 sites/app.campground.gg/src/components/index/sticky/LandingStickyEncryption.tsx create mode 100644 sites/app.campground.gg/src/components/index/sticky/LandingStickyLists.tsx create mode 100644 sites/app.campground.gg/src/components/index/sticky/LandingStickyProfile.tsx create mode 100644 sites/app.campground.gg/src/components/index/sticky/LandingStickySelfHosts.tsx create mode 100644 sites/app.campground.gg/src/components/index/sticky/LandingStickyThemes.tsx create mode 100644 sites/app.campground.gg/src/components/index/sticky/animations.ts diff --git a/sites/app.campground.gg/src/components/ObservabilityDisplay.tsx b/sites/app.campground.gg/src/components/ObservabilityDisplay.tsx new file mode 100644 index 0000000..9d9f197 --- /dev/null +++ b/sites/app.campground.gg/src/components/ObservabilityDisplay.tsx @@ -0,0 +1,73 @@ +import { keyframes } from "@emotion/react"; +import { Box } from "@mui/joy"; +import React, { ReactNode } from "react"; + +type Element = { + elementId: string; + node: ReactNode; +}; + +type Props = { + threshold?: number; + observeQuery: string; + children: Element[] | Element; +}; +type State = { + displayIds: string[]; +}; + +export default class ObservabilityDisplay extends React.Component { + intersectionObserver?: IntersectionObserver; + items: Element[]; + + static appearAnimation = keyframes` + 0% { + opacity: 0; + } + 100% { + opacity: 100%; + } + `; + + constructor(props: Props) { + super(props); + + this.state = { displayIds: [] }; + this.items = Array.isArray(this.props.children) ? this.props.children : [this.props.children]; + } + + callback(entries: IntersectionObserverEntry[], _: IntersectionObserver) { + console.log(entries.map((x) => ({ targetId: x.target.id, isIntersecting: x.isIntersecting }))); + this.setState({ displayIds: entries.filter(x => x.isIntersecting).map(x => x.target.id) }); + } + + componentDidMount(): void { + const options = { + root: null, + rootMargin: `0px`, + threshold: this.props.threshold, + }; + this.intersectionObserver = new IntersectionObserver(this.callback.bind(this), options); + + for (const item of this.items) + this.intersectionObserver.observe(document.querySelector(`#${item.elementId}`)!); + } + + componentWillUnmount(): void { + + } + + render(): React.ReactNode { + const { displayIds } = this.state; + + return ( + + {this.items.map(({ elementId, node }) => + + {node} + + )} + + ); + } +} \ No newline at end of file diff --git a/sites/app.campground.gg/src/components/index/LandingSection.tsx b/sites/app.campground.gg/src/components/index/LandingSection.tsx index bccc872..d8e7ac3 100644 --- a/sites/app.campground.gg/src/components/index/LandingSection.tsx +++ b/sites/app.campground.gg/src/components/index/LandingSection.tsx @@ -5,6 +5,7 @@ import { FormattedMessage } from "react-intl"; import PrimaryButton from "../PrimaryButton"; type Props = { + id: string; subtitle: string; title: string; description: string; @@ -19,10 +20,10 @@ export default class LandingSection extends React.Component { } render() { - const { subtitle, title, description, learnMore, learnMoreHref, icon } = this.props; + const { id, subtitle, title, description, learnMore, learnMoreHref, icon } = this.props; return ( - + diff --git a/sites/app.campground.gg/src/components/index/sticky/LandingStickyCampfire.tsx b/sites/app.campground.gg/src/components/index/sticky/LandingStickyCampfire.tsx new file mode 100644 index 0000000..5e88286 --- /dev/null +++ b/sites/app.campground.gg/src/components/index/sticky/LandingStickyCampfire.tsx @@ -0,0 +1,77 @@ +import { Avatar, Box, ColorPaletteProp, Sheet, Stack, Typography } from "@mui/joy"; +import { Theme } from "@mui/joy/styles/types"; +import { IconCaretDown, IconClockFilled, IconFileTextFilled, IconHash, IconMessageFilled, IconMountainFilled } from "@tabler/icons-react"; +import { SystemStyleObject } from "@mui/system/styleFunctionSx/styleFunctionSx"; +import React, { ReactNode } from "react"; +import { floatingAnimation } from "./animations"; + +export default function LandingStickyCampfires() { + return ( + + + + } name="Mod discussions" /> + } name="Suspicious activity" /> + + } name="Mod Schedule" /> + } name="Warnings" /> + + + + } name="Game discussions" /> + } name="Media" /> + + + + } name="Chat" /> + } name="Player Schedule" /> + } name="Suggestions" /> + + } name="Slayer's Profile" /> + } name="Slayer's Gameplay" /> + + + ) +} +function LandingStickyCampfire({ sx, name, description, color, children }: { sx?: SystemStyleObject, name: string, description: string, color: ColorPaletteProp, children: ReactNode[] | ReactNode }) { + return ( + ({ position: "absolute", minWidth: 400, background: theme.vars.palette.background.level2, borderRadius: 16, boxShadow: theme.vars.shadow.xl, ...sx })}> + + + + {name[0]} + + + {name} + {description} + + + + + + {children} + + + + ); +} +function LandingStickyCampfiresChannel({ highlighted, icon, name }: { highlighted?: boolean, icon: React.ReactNode, name: string }) { + return ( + ({ borderRadius: 8, px: 2, py: 1, backgroundColor: highlighted ? theme.vars.palette.background.level4 : theme.vars.palette.background.level2 })}> + + {icon} + {name} + + + ) +} +function LandingStickyCampfiresCategory({ name }: { name: string }) { + return ( + ({ borderRadius: 8, px: 0, py: 1, backgroundColor: theme.vars.palette.background.level2 })}> + + + {name} + + + ) +} \ No newline at end of file diff --git a/sites/app.campground.gg/src/components/index/sticky/LandingStickyEncryption.tsx b/sites/app.campground.gg/src/components/index/sticky/LandingStickyEncryption.tsx new file mode 100644 index 0000000..8a7bd1e --- /dev/null +++ b/sites/app.campground.gg/src/components/index/sticky/LandingStickyEncryption.tsx @@ -0,0 +1,96 @@ +import { Alert, Avatar, Card, CardContent, ColorPaletteProp, Stack, Typography } from "@mui/joy"; +import { Theme } from "@mui/joy/styles/types"; +import { SystemStyleObject } from "@mui/system/styleFunctionSx/styleFunctionSx"; +import { IconLockFilled } from "@tabler/icons-react"; +import React from "react"; + +const cardWidth = 500; + +export default function LandingStickyEncryption() { + return ( + + ({ + position: "relative", + width: cardWidth + 60, + "::after": { + content: "''", + position: "absolute", + top: 0, + left: 0, + right: 0, + bottom: 0, + zIndex: 10, + background: `linear-gradient(to bottom, transparent, ${theme.vars.palette.background.body})` + } + })}> + + + + + + }> + Chat is protected with encryption + + + ) +} + +type State = { + text: string; +}; +type Props = { + sx?: SystemStyleObject; + color: ColorPaletteProp; + username: string; +}; + +const aCharCode = "A".charCodeAt(0); +const zCharCode = "z".charCodeAt(0); + +function randomizeCharacter() { + return String.fromCharCode(Math.floor(Math.random() * (zCharCode - aCharCode) + aCharCode)); +} +function randomizeText() { + return Array(30).join().split(",").map(randomizeCharacter).join(""); +} + +class LandingStickyEncryptedMessage extends React.Component { + interval?: NodeJS.Timeout; + constructor(props: Props) { + super(props); + + this.state = { + text: randomizeText(), + } + } + componentDidMount(): void { + this.interval = setInterval(() => this.setState({ text: randomizeText() }), 100); + } + componentWillUnmount(): void { + clearInterval(this.interval); + } + render() { + const { sx, color, username } = this.props; + const { text } = this.state; + + return ( + + + + + {username[0]} + + + + {username} + Today at 12:43pm + + {text} + + + + + ); + } +} + diff --git a/sites/app.campground.gg/src/components/index/sticky/LandingStickyLists.tsx b/sites/app.campground.gg/src/components/index/sticky/LandingStickyLists.tsx new file mode 100644 index 0000000..fdc4620 --- /dev/null +++ b/sites/app.campground.gg/src/components/index/sticky/LandingStickyLists.tsx @@ -0,0 +1,89 @@ +import { keyframes } from "@emotion/react"; +import { Avatar, Box, Card, CardContent, Stack, Typography } from "@mui/joy"; +import { Theme } from "@mui/joy/styles/types"; +import { SystemStyleObject } from "@mui/system/styleFunctionSx/styleFunctionSx"; +import { IconCheck, IconX } from "@tabler/icons-react"; +import React from "react"; + +const appearAnimation = keyframes` + 0% { + opacity: 0; + } + 5% { + opacity: 100%; + } + 65% { + opacity: 100%; + } + 70% { + opacity: 0; + } + 100% { + opacity: 0; + } +`; + +export default function LandingStickyLists() { + return ( + + + + + + + + + ) +} + +type Props = { + sx?: SystemStyleObject; + noCompletionAnimation?: boolean; + animationDelay?: string; + title: string; + description: string; +}; + +function LandingStickyListSubItem(props: Props) { + return ( + + ({ mt: -8, ml: 3, height: 112, width: 30, borderBottomLeftRadius: 12, borderBottom: `solid 3px ${theme.vars.palette.neutral[500]}`, borderLeft: `solid 3px ${theme.vars.palette.neutral[500]}` })}> + + + + + ) +} + +class LandingStickyListItem extends React.Component { + constructor(props: Props) { + super(props); + } + render() { + const { sx, noCompletionAnimation, animationDelay, title, description } = this.props; + + return ( + + + + + + + + + + + + + + {title} + {description} + + + + + + ); + } +} + diff --git a/sites/app.campground.gg/src/components/index/sticky/LandingStickyProfile.tsx b/sites/app.campground.gg/src/components/index/sticky/LandingStickyProfile.tsx new file mode 100644 index 0000000..86cf6e7 --- /dev/null +++ b/sites/app.campground.gg/src/components/index/sticky/LandingStickyProfile.tsx @@ -0,0 +1,46 @@ +import { AspectRatio, Avatar, Badge, Box, Card, CardContent, CardOverflow, Stack, Typography } from "@mui/joy"; +import { floatingAnimation } from "./animations"; + +export default function LandingStickyProfile() { + return ( + ({ animation: `${floatingAnimation} 5s infinite`, border: "none", background: `linear-gradient(to bottom right, ${theme.vars.palette.danger[1000]}, ${theme.vars.palette.danger[900]})` })}> + + + ({ background: `linear-gradient(to bottom right, ${theme.vars.palette.danger[500]}, ${theme.vars.palette.danger[400]})` })}> + + + + + ({ width: 96, height: 96, border: `solid 2px ${theme.vars.palette.background.surface}` })}> + + S + + + + + + + + + Susan + @susan.example.com + 1 Mutual Friend • 2 Mutual Campsites + Hello, I am Susan. 👋 I am an avid book reader and an author. + + + + + Blog: Nineteen Eighty-Four — a must-read + Nineteen Eighty-Four is a dystopian novel by the English writer George Orwell. It was published on 8 June 1949 by Secker & Warburg as Orwell's ninth and final completed book. + + + ({ width: "100%", height: 150, background: `linear-gradient(to bottom, transparent 0%, ${theme.vars.palette.danger[900]} 95%)` })}> + + + + + + + + ) +} diff --git a/sites/app.campground.gg/src/components/index/sticky/LandingStickySelfHosts.tsx b/sites/app.campground.gg/src/components/index/sticky/LandingStickySelfHosts.tsx new file mode 100644 index 0000000..1e8f244 --- /dev/null +++ b/sites/app.campground.gg/src/components/index/sticky/LandingStickySelfHosts.tsx @@ -0,0 +1,50 @@ +import { AspectRatio, Avatar, Box, Card, CardContent, CardOverflow, ColorPaletteProp, Link, Sheet, Stack, Typography } from "@mui/joy"; +import { Theme } from "@mui/joy/styles/types"; +import { SystemStyleObject } from "@mui/system/styleFunctionSx/styleFunctionSx"; +import { floatingAnimation } from "./animations"; + +export default function LandingStickySelfHosts() { + return ( + + + + + ); +} +function LandingStickySelfHost({ name, color, sx }: { name: string; color: ColorPaletteProp; sx?: SystemStyleObject; }) { + return ( + ({ animation: `${floatingAnimation} 5s infinite`, position: "absolute", boxShadow: theme.vars.shadow.xl, minWidth: 600, ...sx })}> + + + ({ background: `linear-gradient(to bottom right, ${theme.vars.palette[color][500]}, ${theme.vars.palette[color][400]})` })}> + + + + + + + + {name[0]} + + + {name} + + + + + ({ backgroundColor: theme.vars.palette.neutral[400], width: 4, height: 16 })} color="neutral" variant="solid"> + + Medium connection + + 127.0.0.1:2025 + + + https://campground.gg + + + + + + + ); +} diff --git a/sites/app.campground.gg/src/components/index/sticky/LandingStickyThemes.tsx b/sites/app.campground.gg/src/components/index/sticky/LandingStickyThemes.tsx new file mode 100644 index 0000000..394c4b0 --- /dev/null +++ b/sites/app.campground.gg/src/components/index/sticky/LandingStickyThemes.tsx @@ -0,0 +1,54 @@ +import { keyframes } from "@emotion/react"; +import { Box, Sheet, Stack, Typography } from "@mui/joy"; +import { IconPaletteFilled } from "@tabler/icons-react"; + +const circularMotion = keyframes` + 0% { + transform: rotate(0deg) translateY(192px) rotate(0deg); + } + 100% { + transform: rotate(360deg) translateY(192px) rotate(-360deg); + } +` +const rainbowBg = keyframes` + 0% { + background-color: #00FFFF; + } + 16.67% { + background-color: #0000FF; + } + 33.33% { + background-color: #FF00FF; + } + 50% { + background-color: #FF0000; + } + 66.67% { + background-color: #FFFF00; + } + 83.33% { + background-color: #00FF00; + } + 100% { + background-color: #00FFFF; + } +` + +export default function LandingStickyThemes() { + return ( + + + + + + + + + + + + + + + ) +} \ No newline at end of file diff --git a/sites/app.campground.gg/src/components/index/sticky/animations.ts b/sites/app.campground.gg/src/components/index/sticky/animations.ts new file mode 100644 index 0000000..7622176 --- /dev/null +++ b/sites/app.campground.gg/src/components/index/sticky/animations.ts @@ -0,0 +1,13 @@ +import { keyframes } from "@emotion/react"; + +export const floatingAnimation = keyframes` + 0% { + transform: translateY(15px); + } + 50% { + transform: translateY(-15px); + } + 100% { + transform: translateY(15px); + } +`; \ No newline at end of file diff --git a/sites/app.campground.gg/src/routes/landing/LandingIndex.tsx b/sites/app.campground.gg/src/routes/landing/LandingIndex.tsx index e886164..0d787e9 100644 --- a/sites/app.campground.gg/src/routes/landing/LandingIndex.tsx +++ b/sites/app.campground.gg/src/routes/landing/LandingIndex.tsx @@ -6,6 +6,13 @@ import { IconBrandDebian, IconCamper, IconCampfire, IconCheckbox, IconLock, Icon import { Box, Button, Grid, Link, Sheet, Stack, Typography } from "@mui/joy"; import PrimaryButton from "../../components/PrimaryButton"; import LandingSection from "../../components/index/LandingSection"; +import ObservabilityDisplay from "../../components/ObservabilityDisplay"; +import LandingStickyCampfires from "../../components/index/sticky/LandingStickyCampfire"; +import LandingStickySelfHosts from "../../components/index/sticky/LandingStickySelfHosts"; +import LandingStickyEncryption from "../../components/index/sticky/LandingStickyEncryption"; +import LandingStickyProfile from "../../components/index/sticky/LandingStickyProfile"; +import LandingStickyLists from "../../components/index/sticky/LandingStickyLists"; +import LandingStickyThemes from "../../components/index/sticky/LandingStickyThemes"; export type Props = { @@ -52,14 +59,8 @@ export default class LandingIndex extends React.Component { {/* Features in the Index */} - - - - Example content - - - } title="home.campfires.title" @@ -68,6 +69,7 @@ export default class LandingIndex extends React.Component { learnMoreHref="/docs/features/campfires" /> } title="home.selfHost.title" @@ -76,6 +78,7 @@ export default class LandingIndex extends React.Component { learnMoreHref="/docs/features/instances" /> } title="home.encryption.title" @@ -84,6 +87,7 @@ export default class LandingIndex extends React.Component { learnMoreHref="/docs/features/encryption" /> } title="home.profiles.title" @@ -92,6 +96,7 @@ export default class LandingIndex extends React.Component { learnMoreHref="/docs/features/profiles" /> } title="home.lists.title" @@ -100,6 +105,7 @@ export default class LandingIndex extends React.Component { learnMoreHref="/docs/features/list-tents" /> } title="home.themes.title" @@ -107,6 +113,18 @@ export default class LandingIndex extends React.Component { learnMore="home.themes.learnMore" learnMoreHref="/docs/features/themes" /> + + + + {{ elementId: "campfires", node: }} + {{ elementId: "selfHost", node: }} + {{ elementId: "encryption", node: }} + {{ elementId: "profiles", node: }} + {{ elementId: "lists", node: }} + {{ elementId: "themes", node: }} + + + diff --git a/sites/app.campground.gg/src/theme/gen.ts b/sites/app.campground.gg/src/theme/gen.ts index decf04e..1601077 100644 --- a/sites/app.campground.gg/src/theme/gen.ts +++ b/sites/app.campground.gg/src/theme/gen.ts @@ -7,8 +7,10 @@ import { PaletteOptions } from "@mui/joy/styles/types"; import { greyscaleHexColor, mixHexColors } from "./color"; export const generateColorScheme = (typicalColour: string, background: string, counter: string): Partial => ({ + 1000: mixHexColors(typicalColour, background, 0.95), 950: mixHexColors(typicalColour, background, 0.88), 900: mixHexColors(typicalColour, background, 0.8), + 850: mixHexColors(typicalColour, background, 0.7), 800: mixHexColors(typicalColour, background, 0.6), 700: mixHexColors(typicalColour, background, 0.4), 600: mixHexColors(typicalColour, background, 0.2), diff --git a/sites/app.campground.gg/src/theme/index.ts b/sites/app.campground.gg/src/theme/index.ts index 310e940..d164858 100644 --- a/sites/app.campground.gg/src/theme/index.ts +++ b/sites/app.campground.gg/src/theme/index.ts @@ -20,7 +20,9 @@ declare module "@mui/joy/styles" { } // Add new palette ranges interface PaletteRangeOverrides { + 1000: true; 950: true; + 850: true; ["t-950"]: true; ["t-500"]: true; } @@ -69,18 +71,6 @@ const theme = extendTheme({ }, } } - // primaryColor: "orange", - // colors: { - // pink: ["#ff2661", "#ff2661", "#ff2661", "#ff2661", "#ff2661", "#ff2661", "#ff2661", "#ff2661", "#ff2661", "#ff2661", ], - // red: ["#ff402b", "#ff402b", "#ff402b", "#ff402b", "#ff402b", "#ff402b", "#ff402b", "#ff402b", "#ff402b", "#ff402b", ], - // orange: ["#ff5a26", "#ff5a26", "#ff5a26", "#ff5a26", "#ff5a26", "#ff5a26", "#ff5a26", "#ff5a26", "#ff5a26", "#ff5a26"], - // green: ["#20eb53", "#20eb53", "#20eb53", "#20eb53", "#20eb53", "#20eb53", "#20eb53", "#20eb53", "#20eb53", "#20eb53", ], - // }, - // defaultGradient: { - // from: "orange", - // to: "pink", - // deg: 60 - // } }); export default theme; \ No newline at end of file From a171a636ceb1861c1ded4f96caf0821f62c9a7b2 Mon Sep 17 00:00:00 2001 From: IdkGoodName <31628630+IdkGoodName@users.noreply.github.com> Date: Sat, 20 Sep 2025 19:42:02 +1000 Subject: [PATCH 07/14] fix: further rename Index -> Landing --- .../{index => landing}/DownloadCard.tsx | 0 .../{index => landing}/FeatureCard.tsx | 0 .../LandingBareboneWrapper.tsx | 4 +- .../{index => landing}/LandingFooter.tsx | 4 +- .../{index => landing}/LandingFooterItem.tsx | 2 +- .../LandingFooterSection.tsx | 0 .../{index => landing}/LandingNavbar.tsx | 8 ++-- .../{index => landing}/LandingNavbarItem.tsx | 2 +- .../LandingNavbarPrimary.tsx | 2 +- .../{index => landing}/LandingPageWrapper.tsx | 2 +- .../{index => landing}/LandingSection.tsx | 4 +- .../sticky/LandingStickyCampfire.tsx | 0 .../sticky/LandingStickyEncryption.tsx | 0 .../sticky/LandingStickyLists.tsx | 0 .../sticky/LandingStickyProfile.tsx | 0 .../sticky/LandingStickySelfHosts.tsx | 0 .../sticky/LandingStickyThemes.tsx | 0 .../{index => landing}/sticky/animations.ts | 0 .../src/components/signin/SigninNavbar.tsx | 2 +- .../src/components/signin/SigninWrapper.tsx | 2 +- .../app.campground.gg/src/routes/NotFound.tsx | 10 ++--- sites/app.campground.gg/src/routes/Soon.tsx | 10 ++--- .../src/routes/landing/Downloads.tsx | 34 ++++++++--------- .../src/routes/landing/Features.tsx | 14 +++---- .../src/routes/landing/LandingIndex.tsx | 38 +++++++++---------- 25 files changed, 69 insertions(+), 69 deletions(-) rename sites/app.campground.gg/src/components/{index => landing}/DownloadCard.tsx (100%) rename sites/app.campground.gg/src/components/{index => landing}/FeatureCard.tsx (100%) rename sites/app.campground.gg/src/components/{index => landing}/LandingBareboneWrapper.tsx (73%) rename sites/app.campground.gg/src/components/{index => landing}/LandingFooter.tsx (95%) rename sites/app.campground.gg/src/components/{index => landing}/LandingFooterItem.tsx (90%) rename sites/app.campground.gg/src/components/{index => landing}/LandingFooterSection.tsx (100%) rename sites/app.campground.gg/src/components/{index => landing}/LandingNavbar.tsx (84%) rename sites/app.campground.gg/src/components/{index => landing}/LandingNavbarItem.tsx (88%) rename sites/app.campground.gg/src/components/{index => landing}/LandingNavbarPrimary.tsx (88%) rename sites/app.campground.gg/src/components/{index => landing}/LandingPageWrapper.tsx (83%) rename sites/app.campground.gg/src/components/{index => landing}/LandingSection.tsx (89%) rename sites/app.campground.gg/src/components/{index => landing}/sticky/LandingStickyCampfire.tsx (100%) rename sites/app.campground.gg/src/components/{index => landing}/sticky/LandingStickyEncryption.tsx (100%) rename sites/app.campground.gg/src/components/{index => landing}/sticky/LandingStickyLists.tsx (100%) rename sites/app.campground.gg/src/components/{index => landing}/sticky/LandingStickyProfile.tsx (100%) rename sites/app.campground.gg/src/components/{index => landing}/sticky/LandingStickySelfHosts.tsx (100%) rename sites/app.campground.gg/src/components/{index => landing}/sticky/LandingStickyThemes.tsx (100%) rename sites/app.campground.gg/src/components/{index => landing}/sticky/animations.ts (100%) diff --git a/sites/app.campground.gg/src/components/index/DownloadCard.tsx b/sites/app.campground.gg/src/components/landing/DownloadCard.tsx similarity index 100% rename from sites/app.campground.gg/src/components/index/DownloadCard.tsx rename to sites/app.campground.gg/src/components/landing/DownloadCard.tsx diff --git a/sites/app.campground.gg/src/components/index/FeatureCard.tsx b/sites/app.campground.gg/src/components/landing/FeatureCard.tsx similarity index 100% rename from sites/app.campground.gg/src/components/index/FeatureCard.tsx rename to sites/app.campground.gg/src/components/landing/FeatureCard.tsx diff --git a/sites/app.campground.gg/src/components/index/LandingBareboneWrapper.tsx b/sites/app.campground.gg/src/components/landing/LandingBareboneWrapper.tsx similarity index 73% rename from sites/app.campground.gg/src/components/index/LandingBareboneWrapper.tsx rename to sites/app.campground.gg/src/components/landing/LandingBareboneWrapper.tsx index bd5a76b..ccec18b 100644 --- a/sites/app.campground.gg/src/components/index/LandingBareboneWrapper.tsx +++ b/sites/app.campground.gg/src/components/landing/LandingBareboneWrapper.tsx @@ -18,9 +18,9 @@ export default class LandingBareboneWrapper extends React.Component { const { sx, bodySx, children } = this.props; return ( - + - + {children} diff --git a/sites/app.campground.gg/src/components/index/LandingFooter.tsx b/sites/app.campground.gg/src/components/landing/LandingFooter.tsx similarity index 95% rename from sites/app.campground.gg/src/components/index/LandingFooter.tsx rename to sites/app.campground.gg/src/components/landing/LandingFooter.tsx index 844e750..59446e6 100644 --- a/sites/app.campground.gg/src/components/index/LandingFooter.tsx +++ b/sites/app.campground.gg/src/components/landing/LandingFooter.tsx @@ -15,9 +15,9 @@ export default class LandingFooter extends React.Component { } render() { return ( - + - + } href="https://github.com/Project-Campground">GitHub } href="https://bsky.app/profile/campground.gg">Bluesky diff --git a/sites/app.campground.gg/src/components/index/LandingFooterItem.tsx b/sites/app.campground.gg/src/components/landing/LandingFooterItem.tsx similarity index 90% rename from sites/app.campground.gg/src/components/index/LandingFooterItem.tsx rename to sites/app.campground.gg/src/components/landing/LandingFooterItem.tsx index 40ffc74..cd53efc 100644 --- a/sites/app.campground.gg/src/components/index/LandingFooterItem.tsx +++ b/sites/app.campground.gg/src/components/landing/LandingFooterItem.tsx @@ -15,7 +15,7 @@ export default class LandingFooterItem extends React.Component { const { icon, href, children } = this.props; return ( - + {children} ); diff --git a/sites/app.campground.gg/src/components/index/LandingFooterSection.tsx b/sites/app.campground.gg/src/components/landing/LandingFooterSection.tsx similarity index 100% rename from sites/app.campground.gg/src/components/index/LandingFooterSection.tsx rename to sites/app.campground.gg/src/components/landing/LandingFooterSection.tsx diff --git a/sites/app.campground.gg/src/components/index/LandingNavbar.tsx b/sites/app.campground.gg/src/components/landing/LandingNavbar.tsx similarity index 84% rename from sites/app.campground.gg/src/components/index/LandingNavbar.tsx rename to sites/app.campground.gg/src/components/landing/LandingNavbar.tsx index ac6d295..da518cd 100644 --- a/sites/app.campground.gg/src/components/index/LandingNavbar.tsx +++ b/sites/app.campground.gg/src/components/landing/LandingNavbar.tsx @@ -16,9 +16,9 @@ export default class LandingNavbar extends React.Component { render() { return ( ({ position: "sticky", top: 0, zIndex: 20, backgroundColor: theme.vars.palette.background.transparent })}> - - - + + + @@ -34,7 +34,7 @@ export default class LandingNavbar extends React.Component { - + diff --git a/sites/app.campground.gg/src/components/index/LandingNavbarItem.tsx b/sites/app.campground.gg/src/components/landing/LandingNavbarItem.tsx similarity index 88% rename from sites/app.campground.gg/src/components/index/LandingNavbarItem.tsx rename to sites/app.campground.gg/src/components/landing/LandingNavbarItem.tsx index 6172631..5778f27 100644 --- a/sites/app.campground.gg/src/components/index/LandingNavbarItem.tsx +++ b/sites/app.campground.gg/src/components/landing/LandingNavbarItem.tsx @@ -17,7 +17,7 @@ export default class LandingNavbarItem extends React.Component { render(): React.ReactNode { const { variant, color, children, href } = this.props; return ( - ); diff --git a/sites/app.campground.gg/src/components/index/LandingNavbarPrimary.tsx b/sites/app.campground.gg/src/components/landing/LandingNavbarPrimary.tsx similarity index 88% rename from sites/app.campground.gg/src/components/index/LandingNavbarPrimary.tsx rename to sites/app.campground.gg/src/components/landing/LandingNavbarPrimary.tsx index 074d009..a815b82 100644 --- a/sites/app.campground.gg/src/components/index/LandingNavbarPrimary.tsx +++ b/sites/app.campground.gg/src/components/landing/LandingNavbarPrimary.tsx @@ -17,7 +17,7 @@ export default class LandingNavbarPrimary extends React.Component { const { children, href } = this.props; return ( - + { children } diff --git a/sites/app.campground.gg/src/components/index/LandingPageWrapper.tsx b/sites/app.campground.gg/src/components/landing/LandingPageWrapper.tsx similarity index 83% rename from sites/app.campground.gg/src/components/index/LandingPageWrapper.tsx rename to sites/app.campground.gg/src/components/landing/LandingPageWrapper.tsx index dee5b74..963960d 100644 --- a/sites/app.campground.gg/src/components/index/LandingPageWrapper.tsx +++ b/sites/app.campground.gg/src/components/landing/LandingPageWrapper.tsx @@ -17,7 +17,7 @@ export default class LandingPageWrapper extends React.Component { return ( - + {children} diff --git a/sites/app.campground.gg/src/components/index/LandingSection.tsx b/sites/app.campground.gg/src/components/landing/LandingSection.tsx similarity index 89% rename from sites/app.campground.gg/src/components/index/LandingSection.tsx rename to sites/app.campground.gg/src/components/landing/LandingSection.tsx index d8e7ac3..ed22249 100644 --- a/sites/app.campground.gg/src/components/index/LandingSection.tsx +++ b/sites/app.campground.gg/src/components/landing/LandingSection.tsx @@ -23,8 +23,8 @@ export default class LandingSection extends React.Component { const { id, subtitle, title, description, learnMore, learnMoreHref, icon } = this.props; return ( - - + + {icon} diff --git a/sites/app.campground.gg/src/components/index/sticky/LandingStickyCampfire.tsx b/sites/app.campground.gg/src/components/landing/sticky/LandingStickyCampfire.tsx similarity index 100% rename from sites/app.campground.gg/src/components/index/sticky/LandingStickyCampfire.tsx rename to sites/app.campground.gg/src/components/landing/sticky/LandingStickyCampfire.tsx diff --git a/sites/app.campground.gg/src/components/index/sticky/LandingStickyEncryption.tsx b/sites/app.campground.gg/src/components/landing/sticky/LandingStickyEncryption.tsx similarity index 100% rename from sites/app.campground.gg/src/components/index/sticky/LandingStickyEncryption.tsx rename to sites/app.campground.gg/src/components/landing/sticky/LandingStickyEncryption.tsx diff --git a/sites/app.campground.gg/src/components/index/sticky/LandingStickyLists.tsx b/sites/app.campground.gg/src/components/landing/sticky/LandingStickyLists.tsx similarity index 100% rename from sites/app.campground.gg/src/components/index/sticky/LandingStickyLists.tsx rename to sites/app.campground.gg/src/components/landing/sticky/LandingStickyLists.tsx diff --git a/sites/app.campground.gg/src/components/index/sticky/LandingStickyProfile.tsx b/sites/app.campground.gg/src/components/landing/sticky/LandingStickyProfile.tsx similarity index 100% rename from sites/app.campground.gg/src/components/index/sticky/LandingStickyProfile.tsx rename to sites/app.campground.gg/src/components/landing/sticky/LandingStickyProfile.tsx diff --git a/sites/app.campground.gg/src/components/index/sticky/LandingStickySelfHosts.tsx b/sites/app.campground.gg/src/components/landing/sticky/LandingStickySelfHosts.tsx similarity index 100% rename from sites/app.campground.gg/src/components/index/sticky/LandingStickySelfHosts.tsx rename to sites/app.campground.gg/src/components/landing/sticky/LandingStickySelfHosts.tsx diff --git a/sites/app.campground.gg/src/components/index/sticky/LandingStickyThemes.tsx b/sites/app.campground.gg/src/components/landing/sticky/LandingStickyThemes.tsx similarity index 100% rename from sites/app.campground.gg/src/components/index/sticky/LandingStickyThemes.tsx rename to sites/app.campground.gg/src/components/landing/sticky/LandingStickyThemes.tsx diff --git a/sites/app.campground.gg/src/components/index/sticky/animations.ts b/sites/app.campground.gg/src/components/landing/sticky/animations.ts similarity index 100% rename from sites/app.campground.gg/src/components/index/sticky/animations.ts rename to sites/app.campground.gg/src/components/landing/sticky/animations.ts diff --git a/sites/app.campground.gg/src/components/signin/SigninNavbar.tsx b/sites/app.campground.gg/src/components/signin/SigninNavbar.tsx index 5759123..711a0ec 100644 --- a/sites/app.campground.gg/src/components/signin/SigninNavbar.tsx +++ b/sites/app.campground.gg/src/components/signin/SigninNavbar.tsx @@ -15,7 +15,7 @@ export default class SigninNavbar extends React.Component { - + diff --git a/sites/app.campground.gg/src/components/signin/SigninWrapper.tsx b/sites/app.campground.gg/src/components/signin/SigninWrapper.tsx index eb88dcd..8fafcd4 100644 --- a/sites/app.campground.gg/src/components/signin/SigninWrapper.tsx +++ b/sites/app.campground.gg/src/components/signin/SigninWrapper.tsx @@ -20,7 +20,7 @@ export default class SigninWrapper extends React.Component { const { header, sx, bodySx, children } = this.props; return ( - + ({ diff --git a/sites/app.campground.gg/src/routes/NotFound.tsx b/sites/app.campground.gg/src/routes/NotFound.tsx index 9c1192e..8a1ddb3 100644 --- a/sites/app.campground.gg/src/routes/NotFound.tsx +++ b/sites/app.campground.gg/src/routes/NotFound.tsx @@ -1,6 +1,6 @@ import React from "react"; import { FormattedMessage } from "react-intl"; -import LandingPageWrapper from "../components/index/LandingPageWrapper"; +import LandingPageWrapper from "../components/landing/LandingPageWrapper"; // import { Button, Group, SimpleGrid, Stack, Text } from "@mantine/core"; import { Link, Stack, Typography } from "@mui/joy"; import { IconDoorExit, IconMoodAngryFilled } from "@tabler/icons-react"; @@ -17,14 +17,14 @@ export default class NotFound extends React.Component { render() { return ( - - + + - + - + diff --git a/sites/app.campground.gg/src/routes/Soon.tsx b/sites/app.campground.gg/src/routes/Soon.tsx index 234a8ca..23e0b43 100644 --- a/sites/app.campground.gg/src/routes/Soon.tsx +++ b/sites/app.campground.gg/src/routes/Soon.tsx @@ -1,6 +1,6 @@ import React from "react"; import { FormattedMessage } from "react-intl"; -import LandingPageWrapper from "../components/index/LandingPageWrapper"; +import LandingPageWrapper from "../components/landing/LandingPageWrapper"; // import { Button, Group, SimpleGrid, Stack, Text } from "@mantine/core"; import { Link, Stack, Typography } from "@mui/joy"; import { IconDoorExit, IconMoodSadFilled } from "@tabler/icons-react"; @@ -17,14 +17,14 @@ export default class Soon extends React.Component { render() { return ( - - + + - + - + diff --git a/sites/app.campground.gg/src/routes/landing/Downloads.tsx b/sites/app.campground.gg/src/routes/landing/Downloads.tsx index 14acd54..ee53a39 100644 --- a/sites/app.campground.gg/src/routes/landing/Downloads.tsx +++ b/sites/app.campground.gg/src/routes/landing/Downloads.tsx @@ -1,11 +1,11 @@ import React from "react"; import { FormattedMessage } from "react-intl"; -import LandingPageWrapper from "../../components/index/LandingPageWrapper"; +import LandingPageWrapper from "../../components/landing/LandingPageWrapper"; // import { Button, Group, SimpleGrid, Stack, Text } from "@mantine/core"; import { IconBrandAndroid, IconBrandApple, IconBrandDebian, IconBrandGooglePlay, IconBrandWindows, IconDownload, IconFeather } from "@tabler/icons-react"; import { Grid, Link, Option, Select, Stack, Typography } from "@mui/joy"; import PrimaryButton from "../../components/PrimaryButton"; -import DownloadCard from "../../components/index/DownloadCard"; +import DownloadCard from "../../components/landing/DownloadCard"; export type Props = { @@ -18,23 +18,23 @@ export default class Downloads extends React.Component { render() { return ( - + - - + + - + - + - + }> @@ -49,17 +49,17 @@ export default class Downloads extends React.Component { - + - - + + - + - + @@ -111,15 +111,15 @@ export default class Downloads extends React.Component { - - + + - + - + diff --git a/sites/app.campground.gg/src/routes/landing/Features.tsx b/sites/app.campground.gg/src/routes/landing/Features.tsx index a5c9637..ab357aa 100644 --- a/sites/app.campground.gg/src/routes/landing/Features.tsx +++ b/sites/app.campground.gg/src/routes/landing/Features.tsx @@ -1,10 +1,10 @@ import React from "react"; import { FormattedMessage } from "react-intl"; -import LandingPageWrapper from "../../components/index/LandingPageWrapper"; +import LandingPageWrapper from "../../components/landing/LandingPageWrapper"; // import { Button, Group, SimpleGrid, Stack, Text } from "@mantine/core"; import { IconCalendarFilled, IconCampfireFilled, IconCheckbox, IconFileTextFilled, IconLockFilled, IconServer } from "@tabler/icons-react"; import { Box, Grid, Stack, Typography } from "@mui/joy" -import FeatureCard from "../../components/index/FeatureCard"; +import FeatureCard from "../../components/landing/FeatureCard"; export type Props = { @@ -17,17 +17,17 @@ export default class Features extends React.Component { render() { return ( - - - + + + - + - + { return ( {/* Top motto of the Index */} - + - - + + - + - + - + }> @@ -58,7 +58,7 @@ export default class LandingIndex extends React.Component { {/* Features in the Index */} - + { - + ); } } -class IndexBottomSection extends React.Component { +class LandingBottomSection extends React.Component { constructor(props: {}) { super(props); } @@ -141,7 +141,7 @@ class IndexBottomSection extends React.Component { return ( - +