Hardware page work

This commit is contained in:
Sacha Weatherstone 2022-04-03 00:17:50 +11:00
parent 0770406018
commit 79c4547835
16 changed files with 1123 additions and 129 deletions

View file

@ -1,18 +1,18 @@
// @ts-check
require("dotenv").config();
require('dotenv').config();
/** @type {import('@docusaurus/types').Config} */
const config = {
title: "Meshtastic",
tagline: "Open Source hiking, pilot, skiing and secure GPS mesh communicator",
url: "https://meshtastic.org",
baseUrl: "/",
onBrokenLinks: "throw",
onBrokenMarkdownLinks: "warn",
favicon: "design/web/favicon.ico",
organizationName: "meshtastic",
projectName: "meshtastic",
title: 'Meshtastic',
tagline: 'Open Source hiking, pilot, skiing and secure GPS mesh communicator',
url: 'https://meshtastic.org',
baseUrl: '/',
onBrokenLinks: 'throw',
onBrokenMarkdownLinks: 'warn',
favicon: 'design/web/favicon.ico',
organizationName: 'meshtastic',
projectName: 'meshtastic',
ssrTemplate: `<!DOCTYPE html>
<html <%~ it.htmlAttributes %>>
<head>
@ -57,12 +57,12 @@ const config = {
respectPrefersColorScheme: true,
},
navbar: {
title: "Meshtastic",
title: 'Meshtastic',
hideOnScroll: true,
logo: {
alt: "Meshtastic Logo",
src: "design/logo/svg/Mesh_Logo_Black.svg",
srcDark: "design/logo/svg/Mesh_Logo_White.svg",
alt: 'Meshtastic Logo',
src: 'design/logo/svg/Mesh_Logo_Black.svg',
srcDark: 'design/logo/svg/Mesh_Logo_White.svg',
},
items: [
@ -74,9 +74,9 @@ const config = {
},
*/
{
label: "About Meshtastic",
to: "docs/about",
activeBasePath: "docs/about",
label: 'About Meshtastic',
to: 'docs/about',
activeBasePath: 'docs/about',
},
/*
{
@ -86,20 +86,20 @@ const config = {
},
*/
{
label: "Documentation",
label: 'Documentation',
items: [
{
label: "Getting Started",
to: "docs/getting-started",
label: 'Getting Started',
to: 'docs/getting-started',
},
// FIXME create configuration & settings landing page and adjust path below
{
label: "Configuration & Settings",
to: "docs/settings",
label: 'Configuration & Settings',
to: 'docs/settings',
},
{
label: "Hardware Details",
to: "docs/hardware",
label: 'Hardware Details',
to: 'docs/hardware',
},
/*
{
@ -108,43 +108,43 @@ const config = {
},
*/
{
label: "Meshtastic Software",
to: "docs/software",
label: 'Meshtastic Software',
to: 'docs/software',
},
],
},
{
label: "Contribute",
label: 'Contribute',
items: [
{
label: "Developers",
to: "docs/developers",
label: 'Developers',
to: 'docs/developers',
},
{
label: "Maintaining Documentation",
to: "docs/developers/maintaining-documentation/overview",
label: 'Maintaining Documentation',
to: 'docs/developers/maintaining-documentation/overview',
},
{
label: "Legal",
to: "docs/legal",
label: 'Legal',
to: 'docs/legal',
},
],
},
{
label: "Downloads",
to: "downloads",
activeBasePath: "downloads",
label: 'Downloads',
to: 'downloads',
activeBasePath: 'downloads',
},
{
href: "https://meshtastic.discourse.group",
label: "Forum",
position: "left",
href: 'https://meshtastic.discourse.group',
label: 'Forum',
position: 'left',
},
{
href: "https://github.com/meshtastic/meshtastic",
position: "right",
className: "header-github-link",
"aria-label": "GitHub repository",
href: 'https://github.com/meshtastic/meshtastic',
position: 'right',
className: 'header-github-link',
'aria-label': 'GitHub repository',
},
],
},
@ -152,21 +152,21 @@ const config = {
copyright: `<a href="https://vercel.com/?utm_source=meshtastic&utm_campaign=oss" style="color: var(--ifm-footer-color)">Powered by ▲ Vercel</a> | Meshtastic® is a registered trademark of Geeksville Industries LLC`,
},
algolia: {
appId: "IG2GQB8L3V",
apiKey: "2e4348812173ec7ea6f7879c7032bb21",
indexName: "meshtastic",
appId: 'IG2GQB8L3V',
apiKey: '2e4348812173ec7ea6f7879c7032bb21',
indexName: 'meshtastic',
contextualSearch: false,
searchPagePath: "search",
searchPagePath: 'search',
},
},
plugins: [
() => {
return {
name: "docusaurus-tailwindcss",
name: 'docusaurus-tailwindcss',
configurePostCss(postcssOptions) {
// Appends TailwindCSS and AutoPrefixer.
postcssOptions.plugins.push(require("tailwindcss"));
postcssOptions.plugins.push(require("autoprefixer"));
postcssOptions.plugins.push(require('tailwindcss'));
postcssOptions.plugins.push(require('autoprefixer'));
return postcssOptions;
},
};
@ -174,15 +174,15 @@ const config = {
],
presets: [
[
"@docusaurus/preset-classic",
'@docusaurus/preset-classic',
/** @type {import('@docusaurus/preset-classic').Options} */
{
docs: {
sidebarPath: require.resolve("./sidebars.js"),
editUrl: "https://github.com/meshtastic/meshtastic/edit/master/",
sidebarPath: require.resolve('./sidebars.js'),
editUrl: 'https://github.com/meshtastic/meshtastic/edit/master/',
},
theme: {
customCss: require.resolve("./src/css/custom.css"),
customCss: require.resolve('./src/css/custom.css'),
},
},
],

View file

@ -16,6 +16,7 @@
"@algolia/client-search": "^4.13.0",
"@docusaurus/core": "^2.0.0-beta.18",
"@docusaurus/preset-classic": "^2.0.0-beta.18",
"@headlessui/react": "^1.5.0",
"@mdx-js/react": "^1.6.22",
"autoprefixer": "^10.4.4",
"dotenv": "^16.0.0",
@ -27,7 +28,8 @@
"react-spring": "^9.4.4",
"swr": "^1.2.2",
"tailwindcss": "^3.0.23",
"url-search-params-polyfill": "^8.1.1"
"url-search-params-polyfill": "^8.1.1",
"victory": "^36.3.1"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "^2.0.0-beta.18",

View file

@ -5,6 +5,7 @@ specifiers:
'@docusaurus/core': ^2.0.0-beta.18
'@docusaurus/module-type-aliases': ^2.0.0-beta.18
'@docusaurus/preset-classic': ^2.0.0-beta.18
'@headlessui/react': ^1.5.0
'@mdx-js/react': ^1.6.22
'@meshtastic/eslint-config': ^1.0.7
'@tailwindcss/typography': ^0.5.2
@ -26,11 +27,13 @@ specifiers:
tailwindcss: ^3.0.23
typescript: ^4.6.3
url-search-params-polyfill: ^8.1.1
victory: ^36.3.1
dependencies:
'@algolia/client-search': 4.13.0
'@docusaurus/core': 2.0.0-beta.18_28e7016540b0a32b5f8d7be755522ab7
'@docusaurus/preset-classic': 2.0.0-beta.18_cd2ecee38e568e94b4890eebc445da58
'@headlessui/react': 1.5.0_react-dom@17.0.2+react@17.0.2
'@mdx-js/react': 1.6.22_react@17.0.2
autoprefixer: 10.4.4_postcss@8.4.12
dotenv: 16.0.0
@ -43,6 +46,7 @@ dependencies:
swr: 1.2.2_react@17.0.2
tailwindcss: 3.0.23_autoprefixer@10.4.4
url-search-params-polyfill: 8.1.1
victory: 36.3.1_react@17.0.2
devDependencies:
'@docusaurus/module-type-aliases': 2.0.0-beta.18_react-dom@17.0.2+react@17.0.2
@ -2203,6 +2207,17 @@ packages:
dependencies:
'@hapi/hoek': 9.2.1
/@headlessui/react/1.5.0_react-dom@17.0.2+react@17.0.2:
resolution: {integrity: sha512-aaRnYxBb3MU2FNJf3Ut9RMTUqqU3as0aI1lQhgo2n9Fa67wRu14iOGqx93xB+uMNVfNwZ5B3y/Ndm7qZGuFeMQ==}
engines: {node: '>=10'}
peerDependencies:
react: ^16 || ^17 || ^18
react-dom: ^16 || ^17 || ^18
dependencies:
react: 17.0.2
react-dom: 17.0.2_react@17.0.2
dev: false
/@humanwhocodes/config-array/0.9.5:
resolution: {integrity: sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==}
engines: {node: '>=10.10.0'}
@ -4147,6 +4162,76 @@ packages:
/csstype/3.0.11:
resolution: {integrity: sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==}
/d3-array/1.2.4:
resolution: {integrity: sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw==}
dev: false
/d3-array/2.3.3:
resolution: {integrity: sha512-syv3wp0U5aB6toP2zb2OdBkhTy1MWDsCAaYk6OXJZv+G4u7bSWEmYgxLoFyc88RQUhZYGCebW9a9UD1gFi5+MQ==}
dev: false
/d3-collection/1.0.7:
resolution: {integrity: sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A==}
dev: false
/d3-color/1.4.1:
resolution: {integrity: sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q==}
dev: false
/d3-ease/1.0.7:
resolution: {integrity: sha512-lx14ZPYkhNx0s/2HX5sLFUI3mbasHjSSpwO/KaaNACweVwxUruKyWVcb293wMv1RqTPZyZ8kSZ2NogUZNcLOFQ==}
dev: false
/d3-format/1.4.5:
resolution: {integrity: sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ==}
dev: false
/d3-interpolate/1.4.0:
resolution: {integrity: sha512-V9znK0zc3jOPV4VD2zZn0sDhZU3WAE2bmlxdIwwQPPzPjvyLkd8B3JUVdS1IDUFDkWZ72c9qnv1GK2ZagTZ8EA==}
dependencies:
d3-color: 1.4.1
dev: false
/d3-path/1.0.9:
resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==}
dev: false
/d3-scale/1.0.7:
resolution: {integrity: sha512-KvU92czp2/qse5tUfGms6Kjig0AhHOwkzXG0+PqIJB3ke0WUv088AHMZI0OssO9NCkXt4RP8yju9rpH8aGB7Lw==}
dependencies:
d3-array: 1.2.4
d3-collection: 1.0.7
d3-color: 1.4.1
d3-format: 1.4.5
d3-interpolate: 1.4.0
d3-time: 1.1.0
d3-time-format: 2.3.0
dev: false
/d3-shape/1.3.7:
resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==}
dependencies:
d3-path: 1.0.9
dev: false
/d3-time-format/2.3.0:
resolution: {integrity: sha512-guv6b2H37s2Uq/GefleCDtbe0XZAuy7Wa49VGkPVPMfLL9qObgBST3lEHJBMUp8S7NdLQAGIvr2KXk8Hc98iKQ==}
dependencies:
d3-time: 1.1.0
dev: false
/d3-time/1.1.0:
resolution: {integrity: sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA==}
dev: false
/d3-timer/1.0.10:
resolution: {integrity: sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw==}
dev: false
/d3-voronoi/1.1.4:
resolution: {integrity: sha512-dArJ32hchFsrQ8uMiTBLq256MpnZjeuBtdHpaDlYuQyjU0CVzCJl/BVW+SkszaAeH95D/8gxqAhgx0ouAWAfRg==}
dev: false
/debug/2.6.9:
resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
dependencies:
@ -4240,6 +4325,16 @@ packages:
slash: 3.0.0
dev: false
/delaunator/4.0.1:
resolution: {integrity: sha512-WNPWi1IRKZfCt/qIDMfERkDp93+iZEmOxN2yy4Jg+Xhv8SLk2UTqqbe1sfiipn0and9QrE914/ihdx82Y/Giag==}
dev: false
/delaunay-find/0.0.6:
resolution: {integrity: sha512-1+almjfrnR7ZamBk0q3Nhg6lqSe6Le4vL0WJDSMx4IDbQwTpUTXPjxC00lqLBT8MYsJpPCbI16sIkw9cPsbi7Q==}
dependencies:
delaunator: 4.0.1
dev: false
/depd/1.1.2:
resolution: {integrity: sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=}
engines: {node: '>= 0.6'}
@ -6018,6 +6113,10 @@ packages:
resolution: {integrity: sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=}
dev: true
/json-stringify-safe/5.0.1:
resolution: {integrity: sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=}
dev: false
/json5/1.0.1:
resolution: {integrity: sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==}
hasBin: true
@ -7565,6 +7664,10 @@ packages:
resolution: {integrity: sha512-mKR90fX7Pm5seCOfz8q9F+66VCc1PGsWSBxKbITjfKVQHMNF2zudxHnMdJiB1fRCb+XsbQV9sO9DCkgsMQgBIA==}
dev: false
/react-fast-compare/2.0.4:
resolution: {integrity: sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==}
dev: false
/react-fast-compare/3.2.0:
resolution: {integrity: sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==}
@ -8992,6 +9095,372 @@ packages:
vfile-message: 2.0.4
dev: false
/victory-area/36.3.0_react@17.0.2:
resolution: {integrity: sha512-vf/vR+6k4VyeGOuRvc651fN3ItsU6NoGkHrtafCDmJ/KH9bcwgfQS9uZn0aXHC9Vr9rarbFFTrBC6/gLhBYSRA==}
peerDependencies:
react: ^16.6.0 || ^17.0.0
dependencies:
d3-shape: 1.3.7
lodash: 4.17.21
prop-types: 15.8.1
react: 17.0.2
victory-core: 36.3.0_react@17.0.2
dev: false
/victory-axis/36.3.0_react@17.0.2:
resolution: {integrity: sha512-k4h27pN2RHd1TYLia4SbaFn8NHddf7Mzfmqt4WUCLYmkN+R3xQ3METD+X6kwfZmV6FffclJVoD1Errlar/mGdQ==}
peerDependencies:
react: ^16.6.0 || ^17.0.0
dependencies:
lodash: 4.17.21
prop-types: 15.8.1
react: 17.0.2
victory-core: 36.3.0_react@17.0.2
dev: false
/victory-bar/36.3.0_react@17.0.2:
resolution: {integrity: sha512-8qitdaC2LYzxuQfbmsZLQ8VQksumbofD1ks0PimYM2exnBdo9nKi5GB0zuLVeuxvq36qlXUpPyH1VRUyUnCMPg==}
peerDependencies:
react: ^16.6.0 || ^17.0.0
dependencies:
d3-shape: 1.3.7
lodash: 4.17.21
prop-types: 15.8.1
react: 17.0.2
victory-core: 36.3.0_react@17.0.2
dev: false
/victory-box-plot/36.3.0_react@17.0.2:
resolution: {integrity: sha512-FtRMRMoGxIqOKMx7bzU0h63BPeRh4tiMvR1xZ+n32SJOFFnTC9YwsCLM6o03lBx5af6PegV05JLZs6dVgKEMcA==}
peerDependencies:
react: ^16.6.0 || ^17.0.0
dependencies:
d3-array: 1.2.4
lodash: 4.17.21
prop-types: 15.8.1
react: 17.0.2
victory-core: 36.3.0_react@17.0.2
dev: false
/victory-brush-container/36.3.0_react@17.0.2:
resolution: {integrity: sha512-iaal/Dn5o113TFZ2i4GIApZq6lsfSx9MwD+1cQ8yEC67/Krzn127AfDXfPYKUiFhD+NvmCTg8OGsryt4MEHbsw==}
peerDependencies:
react: ^16.6.0 || ^17.0.0
dependencies:
lodash: 4.17.21
prop-types: 15.8.1
react: 17.0.2
react-fast-compare: 2.0.4
victory-core: 36.3.0_react@17.0.2
dev: false
/victory-brush-line/36.3.0_react@17.0.2:
resolution: {integrity: sha512-idOU6G1xcS780QR7GEEdBqd+48SQPxzo8pxC3eqdN0IUhdIcEZF/untJhehQiQrt8MFvMQLnpW2k1JaqnV2Peg==}
peerDependencies:
react: ^16.6.0 || ^17.0.0
dependencies:
lodash: 4.17.21
prop-types: 15.8.1
react: 17.0.2
react-fast-compare: 2.0.4
victory-core: 36.3.0_react@17.0.2
dev: false
/victory-candlestick/36.3.0_react@17.0.2:
resolution: {integrity: sha512-I2LnJDi/wmYhNyLE3GqJwsxJi/rx0ixY3G5tW3Wp+zmzC3qXfJ8ucU+3qNfL3pj5z5Jda1KYYo0Ei6Rq2k4jwg==}
peerDependencies:
react: ^16.6.0 || ^17.0.0
dependencies:
lodash: 4.17.21
prop-types: 15.8.1
react: 17.0.2
victory-core: 36.3.0_react@17.0.2
dev: false
/victory-canvas/36.3.0_react@17.0.2:
resolution: {integrity: sha512-FQfjjZ7YzBPnVvxg1WMFDeXOcLHRXAD7t6qxS0sDcwGerJ8dn51Iel/Kd+jKiXT25W34pUqMh+cUsGIwkpTsZQ==}
peerDependencies:
react: ^16.6.0 || ^17.0.0
dependencies:
lodash: 4.17.21
prop-types: 15.8.1
react: 17.0.2
victory-core: 36.3.0_react@17.0.2
dev: false
/victory-chart/36.3.0_react@17.0.2:
resolution: {integrity: sha512-8BM/xUavO6ineRzhycehHCvf3NT5Z+8YepdvVOVX6PGJUx9rvmZCAVDlB6fDh7kuDdq5mtDFzos+B+BglC1rcA==}
peerDependencies:
react: ^16.6.0 || ^17.0.0
dependencies:
lodash: 4.17.21
prop-types: 15.8.1
react: 17.0.2
react-fast-compare: 2.0.4
victory-axis: 36.3.0_react@17.0.2
victory-core: 36.3.0_react@17.0.2
victory-polar-axis: 36.3.0_react@17.0.2
victory-shared-events: 36.3.0_react@17.0.2
dev: false
/victory-core/36.3.0_react@17.0.2:
resolution: {integrity: sha512-X75h6FvLCO+9u/PbCkHat7CmcOeJrkTLz0uUhLqryofJN81nfZ7VamRDfw5KxDWYlCB5hmxX+dfjzteaqndgeA==}
peerDependencies:
react: ^16.6.0 || ^17.0.0
dependencies:
d3-ease: 1.0.7
d3-interpolate: 1.4.0
d3-scale: 1.0.7
d3-shape: 1.3.7
d3-timer: 1.0.10
lodash: 4.17.21
prop-types: 15.8.1
react: 17.0.2
react-fast-compare: 2.0.4
dev: false
/victory-create-container/36.3.1_react@17.0.2:
resolution: {integrity: sha512-ved4WQH7UxhQZAHZsRK/B/bqIvQZi6EeHR7CkCgvanjYY3mkCM/avv9TNC5RzrNp/DeRC2xdFoBGVuUaLPLnTw==}
peerDependencies:
react: ^16.6.0 || ^17.0.0
dependencies:
lodash: 4.17.21
react: 17.0.2
victory-brush-container: 36.3.0_react@17.0.2
victory-core: 36.3.0_react@17.0.2
victory-cursor-container: 36.3.0_react@17.0.2
victory-selection-container: 36.3.0_react@17.0.2
victory-voronoi-container: 36.3.1_react@17.0.2
victory-zoom-container: 36.3.0_react@17.0.2
dev: false
/victory-cursor-container/36.3.0_react@17.0.2:
resolution: {integrity: sha512-iR+8R1kEul22tifSxr8lnyR0kJ9Wb4VGCVyLgH3VGiJkmbaTRLt0fvKxP+sFbrVIngxTemiVuFBi+nwi48lpAA==}
peerDependencies:
react: ^16.6.0 || ^17.0.0
dependencies:
lodash: 4.17.21
prop-types: 15.8.1
react: 17.0.2
victory-core: 36.3.0_react@17.0.2
dev: false
/victory-errorbar/36.3.0_react@17.0.2:
resolution: {integrity: sha512-Pa/p/36KH45xBivuJsmHZRiWjVJWAqMzRKZrBrY4sPmItq5KMgmDYJLzMgl4F+ZFCIUt6OQP38MnOq47EgOkFg==}
peerDependencies:
react: ^16.6.0 || ^17.0.0
dependencies:
lodash: 4.17.21
prop-types: 15.8.1
react: 17.0.2
victory-core: 36.3.0_react@17.0.2
dev: false
/victory-group/36.3.0_react@17.0.2:
resolution: {integrity: sha512-JsO/CMxQrGOv+GK55ssTWtcASVyC2Y9kJ0a6xWyGKAWufGDehvdmwg2HxAcx9QeIu9vQ0qQOYc3Yk2/DwW0bJQ==}
peerDependencies:
react: ^16.6.0 || ^17.0.0
dependencies:
lodash: 4.17.21
prop-types: 15.8.1
react: 17.0.2
react-fast-compare: 2.0.4
victory-core: 36.3.0_react@17.0.2
victory-shared-events: 36.3.0_react@17.0.2
dev: false
/victory-histogram/36.3.0_react@17.0.2:
resolution: {integrity: sha512-C1IlANqjiUMOzvpaDQZKLgMVf9wEhYBVm9SpGAHmMSo45fGH89Knp+PgKMFKom2BXjuBPAyZjETdulTKDPOHsw==}
peerDependencies:
react: ^16.6.0 || ^17.0.0
dependencies:
d3-array: 2.3.3
d3-scale: 1.0.7
lodash: 4.17.21
prop-types: 15.8.1
react: 17.0.2
react-fast-compare: 2.0.4
victory-bar: 36.3.0_react@17.0.2
victory-core: 36.3.0_react@17.0.2
dev: false
/victory-legend/36.3.0_react@17.0.2:
resolution: {integrity: sha512-5gaUBXQcJfA4BQpatCG1X/evAgrzBfMIHhbEkwH4jCtt9aVU+b2qMYRs7nw+Rnzz5Cicb6cwajHgem9mv3E04w==}
peerDependencies:
react: ^16.6.0 || ^17.0.0
dependencies:
lodash: 4.17.21
prop-types: 15.8.1
react: 17.0.2
victory-core: 36.3.0_react@17.0.2
dev: false
/victory-line/36.3.0_react@17.0.2:
resolution: {integrity: sha512-qLDHBcmFRMytKACgDt3z6ktuqTNKHvVPifoSrAnORfFlXxMJlGB8+XZAGeAP6DeC5jDOb+sc6DFKzSOIvFLnqA==}
peerDependencies:
react: ^16.6.0 || ^17.0.0
dependencies:
d3-shape: 1.3.7
lodash: 4.17.21
prop-types: 15.8.1
react: 17.0.2
victory-core: 36.3.0_react@17.0.2
dev: false
/victory-pie/36.3.0_react@17.0.2:
resolution: {integrity: sha512-ZApiB4OW2l6vHSxRZpaqklQ9gnOshqqZBCHgcyr2kbx+oLJMeKi+mJbh/YS1btFCPwL7bSSO4EYdBuaGyAX9VA==}
peerDependencies:
react: ^16.6.0 || ^17.0.0
dependencies:
d3-shape: 1.3.7
lodash: 4.17.21
prop-types: 15.8.1
react: 17.0.2
victory-core: 36.3.0_react@17.0.2
dev: false
/victory-polar-axis/36.3.0_react@17.0.2:
resolution: {integrity: sha512-xbxHDMJi3CG1dB8ATiURNg0NVVECk0z82soAwVSA5jPmGRmW4t8ByKBfSsw/ommeDclJ95X8+jtR1Jxd+mjsfw==}
peerDependencies:
react: ^16.6.0 || ^17.0.0
dependencies:
lodash: 4.17.21
prop-types: 15.8.1
react: 17.0.2
victory-core: 36.3.0_react@17.0.2
dev: false
/victory-scatter/36.3.0_react@17.0.2:
resolution: {integrity: sha512-PfgM/y7tV/e1Y3ew5R2wvM1O11+EXoToQ2KR0/WTzybwD6R5OghgbcM1xS2NUCtOeubYDkkXjBogZc0rDyyfjA==}
peerDependencies:
react: ^16.6.0 || ^17.0.0
dependencies:
lodash: 4.17.21
prop-types: 15.8.1
react: 17.0.2
victory-core: 36.3.0_react@17.0.2
dev: false
/victory-selection-container/36.3.0_react@17.0.2:
resolution: {integrity: sha512-RdFkmxoy2HkbZ9ebuj5Mlx+/OTtPjoUO+FYXItc/Le+HWcGNvkhzmyfZJ+JZAi7atwevCEQawsdUHslIf9mZig==}
peerDependencies:
react: ^16.6.0 || ^17.0.0
dependencies:
lodash: 4.17.21
prop-types: 15.8.1
react: 17.0.2
victory-core: 36.3.0_react@17.0.2
dev: false
/victory-shared-events/36.3.0_react@17.0.2:
resolution: {integrity: sha512-XnTzwlRy7uUgBm8NW1tLn4wx3M4lkFO/jA3DHFMYgCVzq+Fu7Tu+BmMPZ8m5DxZFwxKP4HVlYuYKwoQu7yerWA==}
peerDependencies:
react: ^16.6.0 || ^17.0.0
dependencies:
json-stringify-safe: 5.0.1
lodash: 4.17.21
prop-types: 15.8.1
react: 17.0.2
react-fast-compare: 2.0.4
victory-core: 36.3.0_react@17.0.2
dev: false
/victory-stack/36.3.0_react@17.0.2:
resolution: {integrity: sha512-QtW+UReATWUojUyv2II+i0d+RonLRcxFIhCFPO4Eo6tHS7ZqvBQWii0N3FRlbl65h2jW4By+xjoNxyHoSsbJJQ==}
peerDependencies:
react: ^16.6.0 || ^17.0.0
dependencies:
lodash: 4.17.21
prop-types: 15.8.1
react: 17.0.2
react-fast-compare: 2.0.4
victory-core: 36.3.0_react@17.0.2
victory-shared-events: 36.3.0_react@17.0.2
dev: false
/victory-tooltip/36.3.0_react@17.0.2:
resolution: {integrity: sha512-GM8hOmbcKZRQCtWDi9bJrqvjUEryqwXcw8onz5sFGvPPONLu7nYKCO0s6/m3wCHqAWqotPpu6FTtxXSChYJ6kA==}
peerDependencies:
react: ^16.6.0 || ^17.0.0
dependencies:
lodash: 4.17.21
prop-types: 15.8.1
react: 17.0.2
victory-core: 36.3.0_react@17.0.2
dev: false
/victory-voronoi-container/36.3.1_react@17.0.2:
resolution: {integrity: sha512-bFznyx0dLRb84nrGhOslN/e/3mfEGCmlPbvEFv8SGBVZxvAQv2go4byhZx4qvFbcKf2Wyx8svyxCsfS9g/OsEw==}
peerDependencies:
react: ^16.6.0 || ^17.0.0
dependencies:
delaunay-find: 0.0.6
lodash: 4.17.21
prop-types: 15.8.1
react: 17.0.2
react-fast-compare: 2.0.4
victory-core: 36.3.0_react@17.0.2
victory-tooltip: 36.3.0_react@17.0.2
dev: false
/victory-voronoi/36.3.0_react@17.0.2:
resolution: {integrity: sha512-P+DMO+mLtpqsH1rfnLBBKanObnk55X44km+eIiqr3NuFJBVOT5XCaiv2p6gbU1adv5ciAxxpN6KAo8TgZwupgg==}
peerDependencies:
react: ^16.6.0 || ^17.0.0
dependencies:
d3-voronoi: 1.1.4
lodash: 4.17.21
prop-types: 15.8.1
react: 17.0.2
victory-core: 36.3.0_react@17.0.2
dev: false
/victory-zoom-container/36.3.0_react@17.0.2:
resolution: {integrity: sha512-FG+nh5pi4xCP7EBI+rtc0q3U6RrkOW+ophOgpGCpNGswvvuREl+DtdS/dPjYk+Ktt45f1qmVrT26ovJ4IiMKEA==}
peerDependencies:
react: ^16.6.0 || ^17.0.0
dependencies:
lodash: 4.17.21
prop-types: 15.8.1
react: 17.0.2
victory-core: 36.3.0_react@17.0.2
dev: false
/victory/36.3.1_react@17.0.2:
resolution: {integrity: sha512-zqmld8hwkV9ysYRUIwfIR1/smjhLEr+m8XZ5xLPK7Io3BLUEcdeJd7bK/Edb4Scv91DodkF9d5DVmvyzEph89g==}
peerDependencies:
react: ^16.6.0 || ^17.0.0
dependencies:
react: 17.0.2
victory-area: 36.3.0_react@17.0.2
victory-axis: 36.3.0_react@17.0.2
victory-bar: 36.3.0_react@17.0.2
victory-box-plot: 36.3.0_react@17.0.2
victory-brush-container: 36.3.0_react@17.0.2
victory-brush-line: 36.3.0_react@17.0.2
victory-candlestick: 36.3.0_react@17.0.2
victory-canvas: 36.3.0_react@17.0.2
victory-chart: 36.3.0_react@17.0.2
victory-core: 36.3.0_react@17.0.2
victory-create-container: 36.3.1_react@17.0.2
victory-cursor-container: 36.3.0_react@17.0.2
victory-errorbar: 36.3.0_react@17.0.2
victory-group: 36.3.0_react@17.0.2
victory-histogram: 36.3.0_react@17.0.2
victory-legend: 36.3.0_react@17.0.2
victory-line: 36.3.0_react@17.0.2
victory-pie: 36.3.0_react@17.0.2
victory-polar-axis: 36.3.0_react@17.0.2
victory-scatter: 36.3.0_react@17.0.2
victory-selection-container: 36.3.0_react@17.0.2
victory-shared-events: 36.3.0_react@17.0.2
victory-stack: 36.3.0_react@17.0.2
victory-tooltip: 36.3.0_react@17.0.2
victory-voronoi: 36.3.0_react@17.0.2
victory-voronoi-container: 36.3.1_react@17.0.2
victory-zoom-container: 36.3.0_react@17.0.2
dev: false
/wait-on/6.0.1:
resolution: {integrity: sha512-zht+KASY3usTY5u2LgaNqn/Cd8MukxLGjdcZxT2ns5QzDmTFc4XoWBgC+C/na+sMRZTuVygQoMYwdcVjHnYIVw==}
engines: {node: '>=10.0.0'}

54
src/components/Modal.tsx Normal file
View file

@ -0,0 +1,54 @@
import React, { Fragment } from 'react';
import { Dialog, Transition } from '@headlessui/react';
export interface ModalProps {
open: boolean;
onClose: () => void;
children: React.ReactNode;
}
export const Modal = ({ open, onClose, children }: ModalProps): JSX.Element => {
return (
<Transition appear show={open} as={Fragment}>
<Dialog
as="div"
className="fixed inset-0 z-10 overflow-y-auto"
onClose={onClose}
>
<div className="min-h-screen px-4 text-center">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Dialog.Overlay className="fixed inset-0 backdrop-blur-md" />
</Transition.Child>
{/* This element is to trick the browser into centering the modal contents. */}
<span
className="inline-block h-screen align-middle"
aria-hidden="true"
>
&#8203;
</span>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 scale-95"
enterTo="opacity-100 scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
{children}
</Transition.Child>
</div>
</Dialog>
</Transition>
);
};

View file

@ -0,0 +1,25 @@
import React from 'react';
import Layout from '@theme/Layout';
export interface PageLayoutProps {
title: string;
description: string;
children: React.ReactNode;
}
export const PageLayout = ({
title,
description,
children,
}: PageLayoutProps): JSX.Element => {
return (
<Layout title={title} description={description}>
{children}
</Layout>
);
};
export interface ColorModeProps {
children: React.ReactNode;
}

View file

@ -0,0 +1,73 @@
import React, { useState } from 'react';
import { FiExternalLink } from 'react-icons/fi';
import { IoEllipsisHorizontalSharp } from 'react-icons/io5';
import { IDevice } from '@site/src/data/device.js';
import { HardwareModal } from './HardwareModal';
export interface HardwareCard {
device: IDevice;
}
export const HardwareCard = ({ device }: HardwareCard): JSX.Element => {
const [open, setOpen] = useState(false);
return (
<>
<li
className="group relative"
onClick={() => {
setOpen(true);
}}
>
<div className="aspect-w-10 aspect-h-7 block w-full overflow-hidden rounded-lg bg-gray-100">
<div
className={`flex aspect-[4/3] overflow-hidden bg-gradient-to-r ${device.misc.Gradient}`}
>
<img
src={device.misc.ImagePath}
alt=""
className="pointer-events-none m-auto object-cover p-2 group-hover:opacity-75"
/>
</div>
<button type="button" className="absolute inset-0 focus:outline-none">
<span className="sr-only">View details for {name}</span>
</button>
</div>
<div className="flex">
<div>
<p className="pointer-events-none mt-2 block truncate text-sm font-medium text-gray-900">
{device.name}
</p>
<p className="pointer-events-none block text-sm font-medium text-gray-500">
{device.specifications.LoRa}
</p>
</div>
<div className="z-10 ml-auto flex gap-2 p-2 opacity-0 transition-opacity duration-100 ease-in-out group-hover:opacity-100">
<a
href="#"
className="flex rounded-lg border-2 py-1 px-2 hover:border-accent"
>
<FiExternalLink className="m-auto" />
</a>
<a
href="#"
className="flex rounded-lg border-2 py-1 px-2 hover:border-accent"
>
<IoEllipsisHorizontalSharp className="m-auto" />
</a>
</div>
</div>
</li>
<HardwareModal
open={open}
close={() => {
setOpen(false);
}}
device={device}
/>
</>
);
};

View file

@ -0,0 +1,143 @@
import React from 'react';
import { FiBluetooth, FiWifi, FiX } from 'react-icons/fi';
import {
VictoryChart,
VictoryLine,
VictoryPolarAxis,
VictoryTheme,
} from 'victory';
import { Tab } from '@headlessui/react';
import type { IDevice } from '@site/src/data/device';
import { Modal } from '../Modal';
import { VariantSelectButton } from './VariantSelectButton';
export interface HardwareModal {
device: IDevice;
open: boolean;
close: () => void;
}
export const HardwareModal = ({
device,
open,
close,
}: HardwareModal): JSX.Element => {
const colors = ['#428517', '#77D200', '#D6D305', '#EC8E19', '#C92B05'];
return (
<Modal open={open} onClose={close}>
<div className="inline-block w-full max-w-md transform overflow-hidden rounded-2xl bg-base text-left align-middle transition-all md:max-w-2xl md:bg-primary lg:max-w-4xl xl:max-w-6xl">
<div className="flex flex-col md:flex-row">
<div
className={`relative flex aspect-[2/1] rounded-t-2xl bg-gradient-to-r md:rounded-l-2xl md:rounded-tr-none ${device.misc.Gradient}`}
>
<img
src={device.misc.ImagePath}
alt=""
className="pointer-events-none m-auto object-cover p-2 group-hover:opacity-75"
/>
<div className="absolute -bottom-3 right-0 m-auto mr-2 ml-auto flex gap-2 md:bottom-2 md:mr-14 md:mt-2">
{device.features.BLE && (
<div className="flex h-min gap-1 rounded-md bg-blue-500 px-1 text-white shadow-md">
<FiBluetooth className="m-auto" />
<span>Bluetooth</span>
</div>
)}
{device.features.WiFi && (
<div className="m-auto flex h-min gap-1 rounded-md bg-orange-500 px-1 text-white shadow-md">
<FiWifi className="m-auto" />
<span>WiFi</span>
</div>
)}
</div>
</div>
<div
className="absolute right-0 mr-2 flex cursor-pointer rounded-b-full bg-secondary p-3 shadow-md hover:bg-tertiary md:mt-2 md:rounded-full"
onClick={close}
>
<FiX className="m-auto" />
</div>
<div className="md: w-full">
<div className="flex shadow-md md:pb-2">
<VariantSelectButton options={[]} />
</div>
<div className="bg-base p-2 md:p-4">
<Tab.Group as="div" className="rounded-2xl bg-primary p-2">
<Tab.List className="flex gap-2">
<Tab
className={({ selected }) =>
`w-1/3 rounded-md px-3 py-2 text-sm font-medium hover:bg-tertiary ${
selected ? 'bg-secondary shadow-md' : ''
}`
}
>
Info
</Tab>
<Tab
className={({ selected }) =>
`w-1/3 rounded-md px-3 py-2 text-sm font-medium hover:bg-tertiary ${
selected ? 'bg-secondary shadow-md' : ''
}`
}
>
Power
</Tab>
<Tab
className={({ selected }) =>
`w-1/3 rounded-md px-3 py-2 text-sm font-medium hover:bg-tertiary ${
selected ? 'bg-secondary shadow-md' : ''
}`
}
>
Pinout
</Tab>
</Tab.List>
<Tab.Panels as="div" className="">
<Tab.Panel className="h-32">Content 1</Tab.Panel>
<Tab.Panel className="h-96">
<VictoryChart
polar
theme={VictoryTheme.material}
domain={{ y: [0, 10] }}
>
<VictoryPolarAxis
dependentAxis
style={{ axis: { stroke: 'none' } }}
tickFormat={() => ''}
/>
<VictoryPolarAxis
tickValues={[
0,
Math.PI / 2,
Math.PI,
(3 * Math.PI) / 2,
]}
tickFormat={['2π', 'π/2', 'π', '3π/2']}
labelPlacement="vertical"
/>
{[5, 4, 3, 2, 1].map((val, i) => {
return (
<VictoryLine
key={i}
samples={100}
style={{ data: { stroke: colors[i] } }}
y={(d) => val * (1 - Math.cos(d.x))}
/>
);
})}
</VictoryChart>
</Tab.Panel>
<Tab.Panel>Content 3</Tab.Panel>
</Tab.Panels>
</Tab.Group>
</div>
</div>
</div>
</div>
</Modal>
);
};

View file

@ -0,0 +1,86 @@
import React, { Fragment, useState } from 'react';
import { FiCheck } from 'react-icons/fi';
import { HiSelector } from 'react-icons/hi';
import { Listbox, Transition } from '@headlessui/react';
const people = [
{ id: 1, name: 'T-Beam 1.1' },
{ id: 2, name: 'T-Beam 1.0' },
{ id: 3, name: 'T-Beam 0.7' },
];
export interface VariantSelectButtonProps {
options: any[];
}
export const VariantSelectButton = ({
options,
}: VariantSelectButtonProps): JSX.Element => {
const [selected, setSelected] = useState(people[0]);
return (
<Listbox value={selected} onChange={setSelected}>
{({ open }) => (
<>
<div className="relative">
<Listbox.Button className="relative -mt-5 ml-2 flex w-fit gap-1 rounded-lg bg-secondary p-2 py-2 pl-3 pr-10 text-lg font-medium leading-6 shadow-md hover:bg-tertiary md:mt-2">
<span className="block truncate">{selected.name}</span>
<span className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2">
<HiSelector
className="h-5 w-5 text-gray-400"
aria-hidden="true"
/>
</span>
</Listbox.Button>
<Transition
show={open}
as={Fragment}
leave="transition ease-in duration-100"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Listbox.Options className="absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-primary py-1 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm">
{people.map((person) => (
<Listbox.Option
key={person.id}
className={({ active }) =>
`relative cursor-default select-none py-2 pl-3 pr-9 ${
active ? 'bg-indigo-600' : ''
}`
}
value={person}
>
{({ selected, active }) => (
<>
<span
className={`block truncate ${
selected ? 'font-semibold' : 'font-normal'
}`}
>
{person.name}
</span>
{selected ? (
<span
className={`absolute inset-y-0 right-0 flex items-center pr-4 ${
active ? '' : 'text-indigo-600'
}`}
>
<FiCheck className="h-5 w-5" aria-hidden="true" />
</span>
) : null}
</>
)}
</Listbox.Option>
))}
</Listbox.Options>
</Transition>
</div>
</>
)}
</Listbox>
);
};

View file

@ -12,6 +12,19 @@
--ifm-color-primary-lighter: rgb(102, 212, 189);
--ifm-color-primary-lightest: rgb(146, 224, 208);
--ifm-code-font-size: 95%;
--ifm-z-index-fixed: 1;
--accent: #67ea94;
--base: #f3f4f6;
--primary: #ffffff;
--secondary: #e5e7eb;
--tertiary: #d1d5db;
}
[data-theme="dark"] {
--base: #38393B;
--primary: #242526;
--secondary: #18191a;
--tertiary: #4C4E50;
}
.docusaurus-highlight-code-line {
@ -112,10 +125,10 @@ a + .navbar__link > svg {
@layer base {
.markdown {
@apply prose prose-lg dark:prose-invert;
@apply prose prose-lg;
}
.col,
.row {
@apply w-full h-full m-0 p-0 flex-grow;
[data-theme="dark"] .markdown {
@apply prose-invert;
}
}

View file

@ -47,6 +47,7 @@ export interface IDevice {
SuggestedUse: UseCase[];
Stability: Stability;
ImagePath: string;
Gradient: string;
};
features: {
BLE: boolean;

View file

@ -0,0 +1,63 @@
import { IDevice, Stability, UseCase } from '../device';
export const heltec: IDevice = {
name: 'Heltec',
misc: {
Stability: Stability.Stable,
SuggestedUse: [UseCase.Portable],
ImagePath: '/img/hardware/heltec-v2.png',
Gradient: 'from-pink-300 via-purple-300 to-indigo-400',
},
features: {
BLE: true,
WiFi: true,
Modules: [
'cannedMessage',
'externalNotification',
'rangeTest',
'rotaryEncoder',
'storeAndForward',
'telemetry',
],
},
specifications: {
BLEVersion: '4.2',
BLEAntenna: 'Integrated',
WiFiVersion: '2.4GHz 802.11 b/g/n WPA/WPA2/WPA2-Enterprise/SPS',
WiFiAntenna: 'Integrated',
Chipset: 'ESP32',
Driver: 'CH9102',
GNSS: 'NEO-6M',
FlashSize: 4,
Frequencies: [433, 868, 915, 923],
LoRa: 'SX1262',
PSRAM: 8,
RAM: undefined,
},
variants: [
{
name: 'TBeam 0.7',
misc: {
Stability: Stability.Unstable,
},
specifications: {
Driver: 'CP210X',
GNSS: 'NEO-6M',
Frequencies: [868, 915],
},
},
{
name: 'TBeam 1.0',
specifications: {
Frequencies: [868, 915],
},
},
{
name: 'TBeam 1.1',
specifications: {
Driver: 'CP210X',
GNSS: 'NEO-6M',
},
},
],
};

View file

@ -6,6 +6,7 @@ export const rak19003: IDevice = {
Stability: Stability.Stable,
SuggestedUse: [UseCase.Portable],
ImagePath: '/img/hardware/rak/RAK19003.png',
Gradient: 'from-green-300 via-blue-500 to-purple-600',
},
features: {
BLE: true,

View file

@ -5,7 +5,8 @@ export const tbeam: IDevice = {
misc: {
Stability: Stability.Stable,
SuggestedUse: [UseCase.Portable],
ImagePath: '/img/hardware/t-beam-meshtastic.png',
ImagePath: '/img/hardware/tbeam-v1.1.svg',
Gradient: 'from-pink-500 via-red-500 to-yellow-500',
},
features: {
BLE: true,

63
src/data/devices/techo.ts Normal file
View file

@ -0,0 +1,63 @@
import { IDevice, Stability, UseCase } from '../device';
export const techo: IDevice = {
name: 'T-Echo',
misc: {
Stability: Stability.Stable,
SuggestedUse: [UseCase.Portable],
ImagePath: '/img/hardware/t-echo-lilygo.jpg',
Gradient: 'from-gray-700 via-gray-900 to-black',
},
features: {
BLE: true,
WiFi: true,
Modules: [
'cannedMessage',
'externalNotification',
'rangeTest',
'rotaryEncoder',
'storeAndForward',
'telemetry',
],
},
specifications: {
BLEVersion: '4.2',
BLEAntenna: 'Integrated',
WiFiVersion: '2.4GHz 802.11 b/g/n WPA/WPA2/WPA2-Enterprise/SPS',
WiFiAntenna: 'Integrated',
Chipset: 'ESP32',
Driver: 'CH9102',
GNSS: 'NEO-6M',
FlashSize: 4,
Frequencies: [433, 868, 915, 923],
LoRa: 'SX1262',
PSRAM: 8,
RAM: undefined,
},
variants: [
{
name: 'TBeam 0.7',
misc: {
Stability: Stability.Unstable,
},
specifications: {
Driver: 'CP210X',
GNSS: 'NEO-6M',
Frequencies: [868, 915],
},
},
{
name: 'TBeam 1.0',
specifications: {
Frequencies: [868, 915],
},
},
{
name: 'TBeam 1.1',
specifications: {
Driver: 'CP210X',
GNSS: 'NEO-6M',
},
},
],
};

View file

@ -1,15 +1,20 @@
import React from 'react';
import { IDevice } from '../../data/device';
import { tbeam } from '../../data/devices/tbeam';
import { FiPlus } from 'react-icons/fi';
import { HardwareCard } from '../../components/hardware/HardwareCard';
import { PageLayout } from '../../components/PageLayout';
import { heltec } from '../../data/devices/heltec';
import { rak19003 } from '../../data/devices/rak19003';
import Layout from '@theme/Layout';
import { tbeam } from '../../data/devices/tbeam';
import { techo } from '../../data/devices/techo';
const Hardware = (): JSX.Element => {
const [selectedDevice, setSelectedDevice] = React.useState<IDevice>();
const hardware = [
tbeam,
rak19003,
rak19003,
heltec,
techo,
rak19003,
rak19003,
rak19003,
@ -23,65 +28,59 @@ const Hardware = (): JSX.Element => {
];
return (
<Layout title="Hardware" description="Supported hardware">
<div className="m-auto flex w-full flex-grow gap-2">
<div className="flex w-2/3 flex-wrap gap-2 overflow-y-auto p-4">
{hardware.map((device) => (
<div
className={`flex cursor-pointer select-none flex-col divide-y rounded-xl border-2 bg-primaryDark shadow-md transition duration-300 ease-in-out hover:scale-95 ${
selectedDevice?.name === device.name
? 'border-accent'
: 'border-secondaryDark'
}`}
onClick={() => {
setSelectedDevice(device);
}}
>
<div className="flex flex-grow">
<img
draggable="false"
className="m-0 w-48 p-4"
src={device.misc.ImagePath}
/>
{/* <img
draggable="false"
className="mt-auto p-4 m-0 w-48"
src="/img/hardware/rak/RAK19003.png"
/> */}
</div>
<div className="p-2">
<div className="text-lg font-medium">{device.name}</div>
<div className="flex">
<div className="m-auto w-min rounded-full bg-secondaryDark px-2 py-0.5 text-sm">
{device.specifications.Chipset}
</div>
{device.features.WiFi && (
<div className="m-auto w-min rounded-full bg-secondaryDark px-2 py-0.5 text-sm">
WiFi
</div>
)}
{device.features.BLE && (
<div className="m-auto w-min rounded-full bg-secondaryDark px-2 py-0.5 text-sm">
BLE
</div>
)}
</div>
</div>
</div>
))}
</div>
{selectedDevice && (
<div className="my-4 w-1/3 flex-grow flex-grow rounded-l-xl bg-primaryDark">
Selected Device {selectedDevice.name}
<h3>Variants:</h3>
{selectedDevice.variants.map((varitant) => (
<div className="">{varitant.name}</div>
))}
<PageLayout title="Hardware" description="Supported hardware">
<div className="border-b border-gray-200 p-4">
<div className="sm:flex sm:items-baseline">
<h3 className="text-lg font-medium leading-6 text-gray-900">
Issues
</h3>
<div className="mt-4 sm:mt-0 sm:ml-10">
<nav className="-mb-px flex space-x-8">
<a
href="#"
className="border-indigo-500 text-indigo-600"
aria-current={'page'}
>
Devices
</a>
<a
href="#"
className="hover:border-gray-300', 'whitespace-nowrap border-b-2 border-transparent
px-1 pb-4 text-sm font-medium text-gray-500 hover:text-gray-700"
>
Antennas
</a>
</nav>
</div>
)}
</div>
</div>
</Layout>
<div className="mx-auto max-w-7xl py-8 px-4 sm:px-6 lg:px-8">
<ul
role="list"
className="grid grid-cols-2 gap-x-2 gap-y-4 sm:grid-cols-3 sm:gap-x-6 lg:grid-cols-4 xl:grid-cols-5 xl:gap-x-4"
>
{hardware.map((device, index) => (
<HardwareCard key={index} device={device} />
))}
<li className="relative">
<a
href="https://github.com/meshtastic/Meshtastic-device/issues/new?assignees=&labels=enhancement%2Ctriage&template=New+Board.yml&title=%5BBoard%5D%3A+"
className="flex aspect-[4/3] rounded-lg border-2 border-dashed border-gray-300 hover:border-gray-400"
target="_blank"
rel="noreferrer"
>
<FiPlus className="m-auto h-12 w-12 text-gray-400" />
</a>
<p className="pointer-events-none mt-2 block truncate text-sm font-medium text-gray-900">
New Board
</p>
<p className="pointer-events-none block text-sm font-medium text-gray-500">
Want to support a board?
</p>
</li>
</ul>
</div>
</PageLayout>
);
};

View file

@ -1,15 +1,16 @@
module.exports = {
content: ["./src/**/*.{js,jsx,ts,tsx}"],
content: ['./src/**/*.{js,jsx,ts,tsx}'],
darkMode: 'class',
theme: {
extend: {
colors: {
accent: "#67ea94",
primary: "#f2f2f2",
secondary: "#ffffff",
primaryDark: "#242526",
secondaryDark: "#18191a",
accent: 'var(--accent)',
base: 'var(--base)',
primary: 'var(--primary)',
secondary: 'var(--secondary)',
tertiary: 'var(--tertiary)',
},
},
},
plugins: [require("@tailwindcss/typography")],
plugins: [require('@tailwindcss/typography')],
};