mirror of
https://github.com/Myzel394/kleckrelay-docs.git
synced 2025-06-18 15:35:28 +02:00
feat: Add ConfigGenerator.tsx
This commit is contained in:
parent
7aa2325a9d
commit
4a15e90aed
7
docs/self-host/config-generator.mdx
Normal file
7
docs/self-host/config-generator.mdx
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 1
|
||||||
|
title: Config Generator
|
||||||
|
---
|
||||||
|
import ConfigGenerator from "../../src/components/ConfigGeneratorFeatures/ConfigGenerator";
|
||||||
|
|
||||||
|
<ConfigGenerator />
|
@ -113,6 +113,19 @@ const config = {
|
|||||||
darkTheme: darkCodeTheme,
|
darkTheme: darkCodeTheme,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
plugins: [
|
||||||
|
async function TailwindPlugin(context, options) {
|
||||||
|
return {
|
||||||
|
name: "docusaurus-tailwindcss",
|
||||||
|
configurePostCss(postcssOptions) {
|
||||||
|
// Appends TailwindCSS and AutoPrefixer.
|
||||||
|
postcssOptions.plugins.push(require("tailwindcss"));
|
||||||
|
postcssOptions.plugins.push(require("autoprefixer"));
|
||||||
|
return postcssOptions;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = config;
|
module.exports = config;
|
||||||
|
292
package-lock.json
generated
292
package-lock.json
generated
@ -1,19 +1,25 @@
|
|||||||
{
|
{
|
||||||
"name": "kleckrelay-docs",
|
"name": "KleckRelay-Docs",
|
||||||
"version": "0.0.0",
|
"version": "0.0.1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"version": "0.0.0",
|
"name": "KleckRelay-Docs",
|
||||||
|
"version": "0.0.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@docusaurus/core": "2.3.1",
|
"@docusaurus/core": "2.3.1",
|
||||||
"@docusaurus/preset-classic": "2.3.1",
|
"@docusaurus/preset-classic": "2.3.1",
|
||||||
"@mdx-js/react": "^1.6.22",
|
"@mdx-js/react": "^1.6.22",
|
||||||
|
"autoprefixer": "^10.4.14",
|
||||||
"clsx": "^1.2.1",
|
"clsx": "^1.2.1",
|
||||||
|
"crypto-random-string": "^5.0.0",
|
||||||
|
"openpgp": "^5.7.0",
|
||||||
|
"postcss": "^8.4.21",
|
||||||
"prism-react-renderer": "^1.3.5",
|
"prism-react-renderer": "^1.3.5",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-dom": "^17.0.2"
|
"react-dom": "^17.0.2",
|
||||||
|
"tailwindcss": "^3.2.7"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@docusaurus/module-type-aliases": "2.3.1",
|
"@docusaurus/module-type-aliases": "2.3.1",
|
||||||
@ -3645,6 +3651,35 @@
|
|||||||
"acorn": "^8"
|
"acorn": "^8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/acorn-node": {
|
||||||
|
"version": "1.8.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz",
|
||||||
|
"integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==",
|
||||||
|
"dependencies": {
|
||||||
|
"acorn": "^7.0.0",
|
||||||
|
"acorn-walk": "^7.0.0",
|
||||||
|
"xtend": "^4.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/acorn-node/node_modules/acorn": {
|
||||||
|
"version": "7.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
|
||||||
|
"integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
|
||||||
|
"bin": {
|
||||||
|
"acorn": "bin/acorn"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/acorn-node/node_modules/acorn-walk": {
|
||||||
|
"version": "7.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz",
|
||||||
|
"integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/acorn-walk": {
|
"node_modules/acorn-walk": {
|
||||||
"version": "8.2.0",
|
"version": "8.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
|
||||||
@ -3863,6 +3898,17 @@
|
|||||||
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
|
||||||
"integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA=="
|
"integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/asn1.js": {
|
||||||
|
"version": "5.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz",
|
||||||
|
"integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==",
|
||||||
|
"dependencies": {
|
||||||
|
"bn.js": "^4.0.0",
|
||||||
|
"inherits": "^2.0.1",
|
||||||
|
"minimalistic-assert": "^1.0.0",
|
||||||
|
"safer-buffer": "^2.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/at-least-node": {
|
"node_modules/at-least-node": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
|
||||||
@ -4059,6 +4105,11 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/bn.js": {
|
||||||
|
"version": "4.12.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
|
||||||
|
"integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
|
||||||
|
},
|
||||||
"node_modules/body-parser": {
|
"node_modules/body-parser": {
|
||||||
"version": "1.20.1",
|
"version": "1.20.1",
|
||||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
|
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
|
||||||
@ -4934,11 +4985,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/crypto-random-string": {
|
"node_modules/crypto-random-string": {
|
||||||
"version": "2.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-5.0.0.tgz",
|
||||||
"integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==",
|
"integrity": "sha512-KWjTXWwxFd6a94m5CdRGW/t82Tr8DoBc9dNnPCAbFI1EBweN6v1tv8y4Y1m7ndkp/nkIBRxUxAzpaBnR2k3bcQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"type-fest": "^2.12.2"
|
||||||
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=14.16"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/css-declaration-sorter": {
|
"node_modules/css-declaration-sorter": {
|
||||||
@ -5308,6 +5365,14 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/defined": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/del": {
|
"node_modules/del": {
|
||||||
"version": "6.1.1",
|
"version": "6.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz",
|
||||||
@ -5405,6 +5470,27 @@
|
|||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
|
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
|
||||||
},
|
},
|
||||||
|
"node_modules/detective": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==",
|
||||||
|
"dependencies": {
|
||||||
|
"acorn-node": "^1.8.2",
|
||||||
|
"defined": "^1.0.0",
|
||||||
|
"minimist": "^1.2.6"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"detective": "bin/detective.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/didyoumean": {
|
||||||
|
"version": "1.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
|
||||||
|
"integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw=="
|
||||||
|
},
|
||||||
"node_modules/dir-glob": {
|
"node_modules/dir-glob": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
|
||||||
@ -5416,6 +5502,11 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/dlv": {
|
||||||
|
"version": "1.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
|
||||||
|
"integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="
|
||||||
|
},
|
||||||
"node_modules/dns-equal": {
|
"node_modules/dns-equal": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
|
||||||
@ -8121,6 +8212,14 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/object-hash": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/object-inspect": {
|
"node_modules/object-inspect": {
|
||||||
"version": "1.12.3",
|
"version": "1.12.3",
|
||||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
|
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
|
||||||
@ -8224,6 +8323,17 @@
|
|||||||
"opener": "bin/opener-bin.js"
|
"opener": "bin/opener-bin.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/openpgp": {
|
||||||
|
"version": "5.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/openpgp/-/openpgp-5.7.0.tgz",
|
||||||
|
"integrity": "sha512-wchYJQfFbSaocUvUIYqNrWD+lRSmFSG1d3Ak2CHeXFocDSEsf7Uc1zUzHjSdlZPTvGeeXPQ+MJrwVtalL4QCBg==",
|
||||||
|
"dependencies": {
|
||||||
|
"asn1.js": "^5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/p-cancelable": {
|
"node_modules/p-cancelable": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
|
||||||
@ -8478,6 +8588,14 @@
|
|||||||
"url": "https://github.com/sponsors/jonschlinkert"
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/pify": {
|
||||||
|
"version": "2.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
|
||||||
|
"integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/pkg-dir": {
|
"node_modules/pkg-dir": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
|
||||||
@ -8667,6 +8785,68 @@
|
|||||||
"postcss": "^8.2.15"
|
"postcss": "^8.2.15"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/postcss-import": {
|
||||||
|
"version": "14.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-14.1.0.tgz",
|
||||||
|
"integrity": "sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==",
|
||||||
|
"dependencies": {
|
||||||
|
"postcss-value-parser": "^4.0.0",
|
||||||
|
"read-cache": "^1.0.0",
|
||||||
|
"resolve": "^1.1.7"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"postcss": "^8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/postcss-js": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz",
|
||||||
|
"integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==",
|
||||||
|
"dependencies": {
|
||||||
|
"camelcase-css": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^12 || ^14 || >= 16"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/postcss/"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"postcss": "^8.4.21"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/postcss-load-config": {
|
||||||
|
"version": "3.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz",
|
||||||
|
"integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==",
|
||||||
|
"dependencies": {
|
||||||
|
"lilconfig": "^2.0.5",
|
||||||
|
"yaml": "^1.10.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/postcss/"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"postcss": ">=8.0.9",
|
||||||
|
"ts-node": ">=9.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"postcss": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"ts-node": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/postcss-loader": {
|
"node_modules/postcss-loader": {
|
||||||
"version": "7.0.2",
|
"version": "7.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.0.2.tgz",
|
||||||
@ -8850,6 +9030,24 @@
|
|||||||
"postcss": "^8.1.0"
|
"postcss": "^8.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/postcss-nested": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==",
|
||||||
|
"dependencies": {
|
||||||
|
"postcss-selector-parser": "^6.0.10"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/postcss/"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"postcss": "^8.2.14"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/postcss-normalize-charset": {
|
"node_modules/postcss-normalize-charset": {
|
||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz",
|
||||||
@ -9283,6 +9481,17 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"node_modules/quick-lru": {
|
||||||
|
"version": "5.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
|
||||||
|
"integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/randombytes": {
|
"node_modules/randombytes": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
|
||||||
@ -9621,6 +9830,14 @@
|
|||||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/read-cache": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
|
||||||
|
"dependencies": {
|
||||||
|
"pify": "^2.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/readable-stream": {
|
"node_modules/readable-stream": {
|
||||||
"version": "3.6.2",
|
"version": "3.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||||
@ -11014,6 +11231,57 @@
|
|||||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/tailwindcss": {
|
||||||
|
"version": "3.2.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.7.tgz",
|
||||||
|
"integrity": "sha512-B6DLqJzc21x7wntlH/GsZwEXTBttVSl1FtCzC8WP4oBc/NKef7kaax5jeihkkCEWc831/5NDJ9gRNDK6NEioQQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"arg": "^5.0.2",
|
||||||
|
"chokidar": "^3.5.3",
|
||||||
|
"color-name": "^1.1.4",
|
||||||
|
"detective": "^5.2.1",
|
||||||
|
"didyoumean": "^1.2.2",
|
||||||
|
"dlv": "^1.1.3",
|
||||||
|
"fast-glob": "^3.2.12",
|
||||||
|
"glob-parent": "^6.0.2",
|
||||||
|
"is-glob": "^4.0.3",
|
||||||
|
"lilconfig": "^2.0.6",
|
||||||
|
"micromatch": "^4.0.5",
|
||||||
|
"normalize-path": "^3.0.0",
|
||||||
|
"object-hash": "^3.0.0",
|
||||||
|
"picocolors": "^1.0.0",
|
||||||
|
"postcss": "^8.0.9",
|
||||||
|
"postcss-import": "^14.1.0",
|
||||||
|
"postcss-js": "^4.0.0",
|
||||||
|
"postcss-load-config": "^3.1.4",
|
||||||
|
"postcss-nested": "6.0.0",
|
||||||
|
"postcss-selector-parser": "^6.0.11",
|
||||||
|
"postcss-value-parser": "^4.2.0",
|
||||||
|
"quick-lru": "^5.1.1",
|
||||||
|
"resolve": "^1.22.1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"tailwind": "lib/cli.js",
|
||||||
|
"tailwindcss": "lib/cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.13.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"postcss": "^8.0.9"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/tailwindcss/node_modules/glob-parent": {
|
||||||
|
"version": "6.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
|
||||||
|
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
|
||||||
|
"dependencies": {
|
||||||
|
"is-glob": "^4.0.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.13.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/tapable": {
|
"node_modules/tapable": {
|
||||||
"version": "2.2.1",
|
"version": "2.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
|
||||||
@ -11375,6 +11643,14 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/unique-string/node_modules/crypto-random-string": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/unist-builder": {
|
"node_modules/unist-builder": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-2.0.3.tgz",
|
||||||
|
@ -18,10 +18,15 @@
|
|||||||
"@docusaurus/core": "2.3.1",
|
"@docusaurus/core": "2.3.1",
|
||||||
"@docusaurus/preset-classic": "2.3.1",
|
"@docusaurus/preset-classic": "2.3.1",
|
||||||
"@mdx-js/react": "^1.6.22",
|
"@mdx-js/react": "^1.6.22",
|
||||||
|
"autoprefixer": "^10.4.14",
|
||||||
"clsx": "^1.2.1",
|
"clsx": "^1.2.1",
|
||||||
|
"crypto-random-string": "^5.0.0",
|
||||||
|
"openpgp": "^5.7.0",
|
||||||
|
"postcss": "^8.4.21",
|
||||||
"prism-react-renderer": "^1.3.5",
|
"prism-react-renderer": "^1.3.5",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-dom": "^17.0.2"
|
"react-dom": "^17.0.2",
|
||||||
|
"tailwindcss": "^3.2.7"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@docusaurus/module-type-aliases": "2.3.1",
|
"@docusaurus/module-type-aliases": "2.3.1",
|
||||||
|
340
src/components/ConfigGeneratorFeatures/ConfigGenerator.tsx
Normal file
340
src/components/ConfigGeneratorFeatures/ConfigGenerator.tsx
Normal file
@ -0,0 +1,340 @@
|
|||||||
|
import React, {ReactElement, useState} from "react";
|
||||||
|
import * as openpgp from "openpgp/lightweight";
|
||||||
|
import cryptoRandomString from "crypto-random-string";
|
||||||
|
|
||||||
|
export default function ConfigGenerator(): ReactElement {
|
||||||
|
const [domain, setDomain] = useState<string>("");
|
||||||
|
const [mailDomain, setMailDomain] = useState<string>("");
|
||||||
|
const [apiDomain, setApiDomain] = useState<string>("");
|
||||||
|
const [admins, setAdmins] = useState<string[]>([]);
|
||||||
|
const [tempAdminValue, setTempAdminValue] = useState<string>("");
|
||||||
|
const [dockerServicesPrefix, setDockerServicesPrefix] = useState<string>("kleckrelay_");
|
||||||
|
|
||||||
|
const [status, setStatus] = useState<"input" | "loading" | "display">("input");
|
||||||
|
|
||||||
|
const [privateKeys, setPrivateKeys] = useState<{
|
||||||
|
serverKey: string;
|
||||||
|
dkimKey: string;
|
||||||
|
kleckSecret: string;
|
||||||
|
dbPassword: string;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
if (status === "loading") {
|
||||||
|
return (
|
||||||
|
<h3>
|
||||||
|
Generating keys...
|
||||||
|
</h3>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === "display") {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col space-y-5">
|
||||||
|
<div>
|
||||||
|
<h2>
|
||||||
|
Here's your <code>.env</code> file:
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<pre>
|
||||||
|
<code>
|
||||||
|
{`
|
||||||
|
API_DOMAIN=${apiDomain}
|
||||||
|
MAIL_DOMAIN=${mailDomain}
|
||||||
|
KLECK_SECRET=${privateKeys!.kleckSecret}
|
||||||
|
SERVER_PRIVATE_KEY=${privateKeys!.serverKey}
|
||||||
|
DKIM_PRIVATE_KEY=${privateKeys!.dkimKey}
|
||||||
|
ADMIN_EMAILS=${admins.join(",")}
|
||||||
|
DB_URI=postgres://kleckrelay:${privateKeys!.dbPassword}@${dockerServicesPrefix}database/kleckrelay
|
||||||
|
`.trimStart().trimEnd()}
|
||||||
|
</code>
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h2>
|
||||||
|
Here's your <code>docker-compose.yml</code> file:
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<pre>
|
||||||
|
<code>
|
||||||
|
{`
|
||||||
|
version: "3"
|
||||||
|
services:
|
||||||
|
${dockerServicesPrefix}database:
|
||||||
|
image: postgres:latest
|
||||||
|
container_name: "${dockerServicesPrefix}database"
|
||||||
|
restart: on-failure:5
|
||||||
|
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: kleckrelay
|
||||||
|
POSTGRES_PASSWORD: ${privateKeys!.dbPassword}
|
||||||
|
POSTGRES_DB: kleckrelay
|
||||||
|
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U user -d mail"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- ./db:/var/lib/postgresql/data
|
||||||
|
|
||||||
|
${dockerServicesPrefix}server:
|
||||||
|
image: myzel394/kleckrelay-server:latest
|
||||||
|
container_name: "${dockerServicesPrefix}server"
|
||||||
|
restart: on-failure:5
|
||||||
|
|
||||||
|
depends_on:
|
||||||
|
${dockerServicesPrefix}database:
|
||||||
|
condition: service_healthy
|
||||||
|
|
||||||
|
cap_add:
|
||||||
|
- NET_BIND_SERVICE
|
||||||
|
- SYS_PTRACE
|
||||||
|
|
||||||
|
ports:
|
||||||
|
- "25:25"
|
||||||
|
- "587:587"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- ./tutorial:/tutorial
|
||||||
|
- ./opendkim_keys:/etc/opendkim/keys
|
||||||
|
- ./certs:/etc/ssl/certs
|
||||||
|
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
|
||||||
|
${dockerServicesPrefix}maid:
|
||||||
|
image: myzel394/kleckrelay-maid:latest
|
||||||
|
container_name: "${dockerServicesPrefix}maid"
|
||||||
|
restart: on-failure:5
|
||||||
|
|
||||||
|
depends_on:
|
||||||
|
${dockerServicesPrefix}database:
|
||||||
|
condition: service_healthy
|
||||||
|
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
|
||||||
|
nginx:
|
||||||
|
image: bunkerity/bunkerweb
|
||||||
|
container_name: nginx
|
||||||
|
restart: on-failure:5
|
||||||
|
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- ./letsencrypt:/etc/letsencrypt
|
||||||
|
|
||||||
|
environment:
|
||||||
|
- MULTISITE=yes
|
||||||
|
- SERVER_NAME=${domain}
|
||||||
|
- USE_REVERSE_PROXY=yes
|
||||||
|
- DISABLE_DEFAULT_SERVER=yes
|
||||||
|
- AUTO_LETS_ENCRYPT=yes
|
||||||
|
|
||||||
|
- ${domain}_REVERSE_PROXY_URL=/
|
||||||
|
- ${domain}_REVERSE_PROXY_HOST=${dockerServicesPrefix}server
|
||||||
|
- ${domain}_ALLOWED_METHODS=GET|POST|PUT|PATCH|DELETE|OPTIONS
|
||||||
|
# Security is too strict
|
||||||
|
- ${domain}_BLOCK_ABUSERS=no
|
||||||
|
- ${domain}_USE_BAD_BEHAVIOR=no
|
||||||
|
- ${domain}_REVERSE_PROXY_INTERCEPT_ERRORS=no
|
||||||
|
`.trimStart().trimEnd()}
|
||||||
|
</code>
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col space-y-5">
|
||||||
|
<div className="flex flex-col space-y-3 w-full">
|
||||||
|
<div className="flex flex-row space-x-2 items-center">
|
||||||
|
<div className="basis-2/12">
|
||||||
|
<label htmlFor="domain" className="text-sm font-medium text-gray-700 dark:text-gray-200">
|
||||||
|
Base Domain
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div className="basis-10/12">
|
||||||
|
<input
|
||||||
|
id="domain"
|
||||||
|
className="px-4 py-2 bg-gray-200 border-none rounded-md dark:bg-gray-900"
|
||||||
|
placeholder="kleckrelay.com"
|
||||||
|
style={{
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "var(--ifm-color-primary-darkest)",
|
||||||
|
}}
|
||||||
|
type="text"
|
||||||
|
value={domain}
|
||||||
|
onChange={event => {
|
||||||
|
setDomain(event.target.value);
|
||||||
|
setApiDomain(`api.${event.target.value}`);
|
||||||
|
setMailDomain(`mail.${event.target.value}`);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-row space-x-2 items-center">
|
||||||
|
<div className="basis-2/12">
|
||||||
|
<label htmlFor="mailDomain" className="text-sm font-medium text-gray-700 dark:text-gray-200">
|
||||||
|
Mail Domain
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div className="basis-10/12">
|
||||||
|
<input
|
||||||
|
id="mailDomain"
|
||||||
|
className="px-4 py-2 bg-gray-200 border-none rounded-md dark:bg-gray-900"
|
||||||
|
placeholder="mail.kleckrelay.com"
|
||||||
|
style={{
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "var(--ifm-color-primary-darkest)",
|
||||||
|
}}
|
||||||
|
type="text"
|
||||||
|
value={mailDomain}
|
||||||
|
onChange={e => setMailDomain(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-row space-x-2 items-center">
|
||||||
|
<div className="basis-2/12">
|
||||||
|
<label htmlFor="apiDomain" className="text-sm font-medium text-gray-700 dark:text-gray-200">
|
||||||
|
API Domain
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div className="basis-10/12">
|
||||||
|
<input
|
||||||
|
id="apiDomain"
|
||||||
|
className="px-4 py-2 bg-gray-200 border-none rounded-md dark:bg-gray-900"
|
||||||
|
placeholder="api.kleckrelay.com"
|
||||||
|
style={{
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "var(--ifm-color-primary-darkest)",
|
||||||
|
}}
|
||||||
|
type="text"
|
||||||
|
value={apiDomain}
|
||||||
|
onChange={e => setApiDomain(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-row space-x-2 items-center">
|
||||||
|
<div className="basis-2/12">
|
||||||
|
<label htmlFor="adminInput" className="text-sm font-medium text-gray-700 dark:text-gray-200">
|
||||||
|
Admins
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div className="basis-10/12">
|
||||||
|
<div className="flex flex-col space-y-2 items-start">
|
||||||
|
<div>
|
||||||
|
<input
|
||||||
|
id="adminInput"
|
||||||
|
className="px-4 py-2 bg-gray-200 border-none rounded-md dark:bg-gray-900"
|
||||||
|
placeholder="marvin@kleckrelay.example"
|
||||||
|
style={{
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "var(--ifm-color-primary-darkest)",
|
||||||
|
}}
|
||||||
|
type="text"
|
||||||
|
value={tempAdminValue}
|
||||||
|
onChange={e => setTempAdminValue(e.target.value)}
|
||||||
|
onKeyDown={event => {
|
||||||
|
if (event.key === "Enter" || event.key === " " || event.key === "," || event.key === ";") {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
if (tempAdminValue) {
|
||||||
|
setAdmins([...admins, tempAdminValue]);
|
||||||
|
setTempAdminValue("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-row space-x-2 items-center">
|
||||||
|
{admins.map((admin, index) => (
|
||||||
|
<button
|
||||||
|
key={admin}
|
||||||
|
aria-label={`Remove ${admin} from admins`}
|
||||||
|
className="flex flex-row space-x-2 items-center px-3 py-1 border-none cursor-pointer bg-gray-300 dark:bg-gray-800 rounded-full"
|
||||||
|
onClick={() => {
|
||||||
|
const newAdmins = [...admins];
|
||||||
|
newAdmins.splice(index, 1);
|
||||||
|
setAdmins(newAdmins);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<p className="text-sm m-0 font-medium text-gray-700 dark:text-gray-200">{admin}</p>
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-row space-x-2 items-center">
|
||||||
|
<div className="basis-2/12">
|
||||||
|
<label htmlFor="dockerServicesPrefix" className="text-sm font-medium text-gray-700 dark:text-gray-200">
|
||||||
|
Docker Services Prefix
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div className="basis-10/12">
|
||||||
|
<input
|
||||||
|
id="dockerServicesPrefix"
|
||||||
|
className="px-4 py-2 bg-gray-200 border-none rounded-md dark:bg-gray-900"
|
||||||
|
placeholder="my_prefix_"
|
||||||
|
style={{
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "var(--ifm-color-primary-darkest)",
|
||||||
|
}}
|
||||||
|
type="text"
|
||||||
|
value={dockerServicesPrefix}
|
||||||
|
onChange={e => setDockerServicesPrefix(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
className="px-4 py-2 cursor-pointer border-none rounded-md text-white"
|
||||||
|
style={{
|
||||||
|
background: "var(--ifm-color-primary-darkest)",
|
||||||
|
}}
|
||||||
|
onClick={async () => {
|
||||||
|
setStatus("loading");
|
||||||
|
|
||||||
|
const {privateKey: serverPrivateKey} = await openpgp.generateKey({
|
||||||
|
type: "ecc",
|
||||||
|
format: "armored",
|
||||||
|
userIDs: [{name: "John Smith", email: "john@example.com"}],
|
||||||
|
passphrase: "",
|
||||||
|
rsaBits: 4096,
|
||||||
|
})
|
||||||
|
const {privateKey: dkimPrivateKey} = await openpgp.generateKey({
|
||||||
|
type: "ecc",
|
||||||
|
format: "armored",
|
||||||
|
userIDs: [{name: "John Smith", email: "john@example.com"}],
|
||||||
|
passphrase: "",
|
||||||
|
rsaBits: 4096,
|
||||||
|
})
|
||||||
|
|
||||||
|
setPrivateKeys({
|
||||||
|
serverKey: btoa(serverPrivateKey),
|
||||||
|
dkimKey: btoa(dkimPrivateKey),
|
||||||
|
kleckSecret: cryptoRandomString({
|
||||||
|
length: 64,
|
||||||
|
type: "hex",
|
||||||
|
}),
|
||||||
|
dbPassword: cryptoRandomString({
|
||||||
|
length: 64,
|
||||||
|
type: "hex",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
setStatus("display");
|
||||||
|
}}>
|
||||||
|
Generate config
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
@ -3,6 +3,10 @@
|
|||||||
* bundles Infima by default. Infima is a CSS framework designed to
|
* bundles Infima by default. Infima is a CSS framework designed to
|
||||||
* work well for content-centric websites.
|
* work well for content-centric websites.
|
||||||
*/
|
*/
|
||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
|
|
||||||
/* You can override the default Infima variables here. */
|
/* You can override the default Infima variables here. */
|
||||||
:root {
|
:root {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user