onboarding ui almost complete

This commit is contained in:
Khalim Conn-Kowlessar 2025-10-14 12:57:52 +00:00
parent cf28e5d9fc
commit ef24c8f773
5 changed files with 767 additions and 906 deletions

549
package-lock.json generated
View file

@ -20,7 +20,7 @@
"@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-navigation-menu": "^1.1.3",
"@radix-ui/react-scroll-area": "^1.2.10",
"@radix-ui/react-select": "^1.2.2",
"@radix-ui/react-select": "^2.2.6",
"@radix-ui/react-separator": "^1.0.3",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-tabs": "^1.1.13",
@ -2841,13 +2841,10 @@
}
},
"node_modules/@radix-ui/number": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.0.1.tgz",
"integrity": "sha512-T5gIdVO2mmPW3NNhjNgEP3cqMXjXL9UbO0BzWcXfvdBs+BohbQxvd/K5hSVKmn9/lbTdsQVKbUcP5WLCwvUbBg==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.13.10"
}
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz",
"integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==",
"license": "MIT"
},
"node_modules/@radix-ui/primitive": {
"version": "1.1.2",
@ -3593,12 +3590,6 @@
}
}
},
"node_modules/@radix-ui/react-scroll-area/node_modules/@radix-ui/number": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz",
"integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==",
"license": "MIT"
},
"node_modules/@radix-ui/react-scroll-area/node_modules/@radix-ui/primitive": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz",
@ -3630,39 +3621,38 @@
}
},
"node_modules/@radix-ui/react-select": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-1.2.2.tgz",
"integrity": "sha512-zI7McXr8fNaSrUY9mZe4x/HC0jTLY9fWNhO1oLWYMQGDXuV4UCivIGTxwioSzO0ZCYX9iSLyWmAh/1TOmX3Cnw==",
"version": "2.2.6",
"resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.2.6.tgz",
"integrity": "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/number": "1.0.1",
"@radix-ui/primitive": "1.0.1",
"@radix-ui/react-collection": "1.0.3",
"@radix-ui/react-compose-refs": "1.0.1",
"@radix-ui/react-context": "1.0.1",
"@radix-ui/react-direction": "1.0.1",
"@radix-ui/react-dismissable-layer": "1.0.4",
"@radix-ui/react-focus-guards": "1.0.1",
"@radix-ui/react-focus-scope": "1.0.3",
"@radix-ui/react-id": "1.0.1",
"@radix-ui/react-popper": "1.1.2",
"@radix-ui/react-portal": "1.0.3",
"@radix-ui/react-primitive": "1.0.3",
"@radix-ui/react-slot": "1.0.2",
"@radix-ui/react-use-callback-ref": "1.0.1",
"@radix-ui/react-use-controllable-state": "1.0.1",
"@radix-ui/react-use-layout-effect": "1.0.1",
"@radix-ui/react-use-previous": "1.0.1",
"@radix-ui/react-visually-hidden": "1.0.3",
"aria-hidden": "^1.1.1",
"react-remove-scroll": "2.5.5"
"@radix-ui/number": "1.1.1",
"@radix-ui/primitive": "1.1.3",
"@radix-ui/react-collection": "1.1.7",
"@radix-ui/react-compose-refs": "1.1.2",
"@radix-ui/react-context": "1.1.2",
"@radix-ui/react-direction": "1.1.1",
"@radix-ui/react-dismissable-layer": "1.1.11",
"@radix-ui/react-focus-guards": "1.1.3",
"@radix-ui/react-focus-scope": "1.1.7",
"@radix-ui/react-id": "1.1.1",
"@radix-ui/react-popper": "1.2.8",
"@radix-ui/react-portal": "1.1.9",
"@radix-ui/react-primitive": "2.1.3",
"@radix-ui/react-slot": "1.2.3",
"@radix-ui/react-use-callback-ref": "1.1.1",
"@radix-ui/react-use-controllable-state": "1.2.2",
"@radix-ui/react-use-layout-effect": "1.1.1",
"@radix-ui/react-use-previous": "1.1.1",
"@radix-ui/react-visually-hidden": "1.2.3",
"aria-hidden": "^1.2.4",
"react-remove-scroll": "^2.6.3"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@ -3674,137 +3664,28 @@
}
},
"node_modules/@radix-ui/react-select/node_modules/@radix-ui/primitive": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.1.tgz",
"integrity": "sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.13.10"
}
},
"node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-arrow": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.0.3.tgz",
"integrity": "sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-primitive": "1.0.3"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-collection": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.0.3.tgz",
"integrity": "sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-compose-refs": "1.0.1",
"@radix-ui/react-context": "1.0.1",
"@radix-ui/react-primitive": "1.0.3",
"@radix-ui/react-slot": "1.0.2"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-compose-refs": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz",
"integrity": "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.13.10"
},
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-context": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.1.tgz",
"integrity": "sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.13.10"
},
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-direction": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.0.1.tgz",
"integrity": "sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.13.10"
},
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz",
"integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==",
"license": "MIT"
},
"node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-dismissable-layer": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.4.tgz",
"integrity": "sha512-7UpBa/RKMoHJYjie1gkF1DlK8l1fdU/VKDpoS3rCCo8YBJR294GwcEHyxHw72yvphJ7ld0AXEcSLAzY2F/WyCg==",
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz",
"integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/primitive": "1.0.1",
"@radix-ui/react-compose-refs": "1.0.1",
"@radix-ui/react-primitive": "1.0.3",
"@radix-ui/react-use-callback-ref": "1.0.1",
"@radix-ui/react-use-escape-keydown": "1.0.3"
"@radix-ui/primitive": "1.1.3",
"@radix-ui/react-compose-refs": "1.1.2",
"@radix-ui/react-primitive": "2.1.3",
"@radix-ui/react-use-callback-ref": "1.1.1",
"@radix-ui/react-use-escape-keydown": "1.1.1"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@ -3816,61 +3697,13 @@
}
},
"node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-focus-guards": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz",
"integrity": "sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==",
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz",
"integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.13.10"
},
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-focus-scope": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.3.tgz",
"integrity": "sha512-upXdPfqI4islj2CslyfUBNlaJCPybbqRHAi1KER7Isel9Q2AtSJ0zRBZv8mWQiFXD2nyAJ4BhC3yXgZ6kMBSrQ==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-compose-refs": "1.0.1",
"@radix-ui/react-primitive": "1.0.3",
"@radix-ui/react-use-callback-ref": "1.0.1"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-id": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.1.tgz",
"integrity": "sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-use-layout-effect": "1.0.1"
},
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0"
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@ -3879,28 +3712,27 @@
}
},
"node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-popper": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.1.2.tgz",
"integrity": "sha512-1CnGGfFi/bbqtJZZ0P/NQY20xdG3E0LALJaLUEoKwPLwl6PPPfbeiCqMVQnhoFRAxjJj4RpBRJzDmUgsex2tSg==",
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz",
"integrity": "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@floating-ui/react-dom": "^2.0.0",
"@radix-ui/react-arrow": "1.0.3",
"@radix-ui/react-compose-refs": "1.0.1",
"@radix-ui/react-context": "1.0.1",
"@radix-ui/react-primitive": "1.0.3",
"@radix-ui/react-use-callback-ref": "1.0.1",
"@radix-ui/react-use-layout-effect": "1.0.1",
"@radix-ui/react-use-rect": "1.0.1",
"@radix-ui/react-use-size": "1.0.1",
"@radix-ui/rect": "1.0.1"
"@radix-ui/react-arrow": "1.1.7",
"@radix-ui/react-compose-refs": "1.1.2",
"@radix-ui/react-context": "1.1.2",
"@radix-ui/react-primitive": "2.1.3",
"@radix-ui/react-use-callback-ref": "1.1.1",
"@radix-ui/react-use-layout-effect": "1.1.1",
"@radix-ui/react-use-rect": "1.1.1",
"@radix-ui/react-use-size": "1.1.1",
"@radix-ui/rect": "1.1.1"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@ -3911,261 +3743,6 @@
}
}
},
"node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-portal": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.3.tgz",
"integrity": "sha512-xLYZeHrWoPmA5mEKEfZZevoVRK/Q43GfzRXkWV6qawIWWK8t6ifIiLQdd7rmQ4Vk1bmI21XhqF9BN3jWf+phpA==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-primitive": "1.0.3"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-primitive": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz",
"integrity": "sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-slot": "1.0.2"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-slot": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz",
"integrity": "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-compose-refs": "1.0.1"
},
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-use-callback-ref": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz",
"integrity": "sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.13.10"
},
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-use-controllable-state": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.1.tgz",
"integrity": "sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-use-callback-ref": "1.0.1"
},
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-use-escape-keydown": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz",
"integrity": "sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-use-callback-ref": "1.0.1"
},
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-use-layout-effect": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.1.tgz",
"integrity": "sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.13.10"
},
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-use-previous": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.0.1.tgz",
"integrity": "sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.13.10"
},
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-use-rect": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.0.1.tgz",
"integrity": "sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/rect": "1.0.1"
},
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-use-size": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.0.1.tgz",
"integrity": "sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-use-layout-effect": "1.0.1"
},
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-visually-hidden": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.0.3.tgz",
"integrity": "sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-primitive": "1.0.3"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-select/node_modules/@radix-ui/rect": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.0.1.tgz",
"integrity": "sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.13.10"
}
},
"node_modules/@radix-ui/react-select/node_modules/react-remove-scroll": {
"version": "2.5.5",
"resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz",
"integrity": "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==",
"license": "MIT",
"dependencies": {
"react-remove-scroll-bar": "^2.3.3",
"react-style-singleton": "^2.2.1",
"tslib": "^2.1.0",
"use-callback-ref": "^1.3.0",
"use-sidecar": "^1.1.2"
},
"engines": {
"node": ">=10"
},
"peerDependencies": {
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-separator": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.7.tgz",

View file

@ -26,7 +26,7 @@
"@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-navigation-menu": "^1.1.3",
"@radix-ui/react-scroll-area": "^1.2.10",
"@radix-ui/react-select": "^1.2.2",
"@radix-ui/react-select": "^2.2.6",
"@radix-ui/react-separator": "^1.0.3",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-tabs": "^1.1.13",

View file

@ -11,55 +11,64 @@ import { Checkbox } from "@/app/shadcn_components/ui/checkbox";
import {
Select,
SelectTrigger,
SelectItem,
SelectContent,
SelectItem,
} from "@/app/shadcn_components/ui/select";
import { Fragment } from "react";
const OnboardingSchema = z.object({
firstName: z.string().min(1, "Required"),
lastName: z.string().min(1, "Required"),
userType: z.enum([
"private_landlord",
"private_tenant",
"social_landlord",
"social_tenant",
"homeowner",
"other",
]),
firstName: z.string().min(1, "First name is required"),
lastName: z.string().min(1, "Last name is required"),
userType: z.enum(
[
"private_landlord",
"private_tenant",
"social_landlord",
"social_tenant",
"homeowner",
"other",
],
{
required_error: "Please tell us who you are",
}
),
propertyCount: z
.enum([
"1",
"25",
"620",
"21+",
"150",
"51100",
"101300",
"3011000",
"1000+",
])
.enum(
[
"1",
"25",
"620",
"21+",
"150",
"51100",
"101300",
"3011000",
"1000+",
],
{
required_error: "Please tell us how many homes youre responsible for",
}
)
.nullable()
.optional(),
goals: z.array(
z.enum([
"access_funding",
"net_zero",
"improve_condition",
"save_money",
"other",
])
goals: z
.array(
z.enum([
"access_funding",
"net_zero",
"improve_condition",
"save_money",
"other",
])
)
.min(1, "Please select at least one goal"),
referralSource: z.enum(
["search", "social_media", "NRLA", "partner", "word_of_mouth", "other"],
{ required_error: "Please tell us how you heard about Domna" }
),
referralSource: z.enum([
"search",
"social_media",
"NRLA",
"partner",
"word_of_mouth",
"other",
]),
nrlaMembershipId: z.string().optional(),
acceptedPrivacy: z.boolean().refine((v) => v === true, {
message: "You must accept the privacy policy",
message: "You must accept our privacy policy to continue",
}),
marketingOptIn: z.boolean().optional(),
});
@ -77,9 +86,23 @@ export default function OnboardingPage() {
marketingOptIn: false,
acceptedPrivacy: false,
},
mode: "onChange",
});
async function handleSubmit(data: OnboardingData) {
const {
register,
handleSubmit,
control,
watch,
setValue,
trigger,
formState: { errors, isValid },
} = form;
const userType = watch("userType");
const referralSource = watch("referralSource");
async function onSubmit(data: OnboardingData) {
await fetch("/api/user/onboard", {
method: "POST",
headers: { "Content-Type": "application/json" },
@ -88,162 +111,383 @@ export default function OnboardingPage() {
router.push("/home");
}
const { register, handleSubmit: submit, watch, setValue } = form;
const userType = watch("userType");
const referralSource = watch("referralSource");
async function nextStep() {
const valid = await trigger(
step === 1
? [
"userType",
...(userType?.includes("landlord") ? ["propertyCount"] : []),
]
: step === 2
? ["goals", "referralSource"]
: []
);
if (valid) setStep((s) => Math.min(s + 1, 3));
}
function prevStep() {
setStep((s) => Math.max(s - 1, 1));
}
return (
<div className="flex min-h-screen items-center justify-center bg-gray-50">
<form
onSubmit={submit(handleSubmit)}
className="bg-white rounded-xl shadow-md p-8 w-full max-w-lg space-y-6"
>
<h1 className="text-2xl font-semibold text-brandblue">
Step {step} of 3
</h1>
<div className="flex bg-gray-50 min-h-screen">
{/* Left image panel */}
<div className="hidden md:flex w-1/2 relative overflow-hidden">
<div
className="absolute inset-0 bg-cover bg-center"
style={{ backgroundImage: "url('/images/Alexandra-Road-Park.webp')" }}
></div>
{step === 1 && (
<div className="space-y-4">
<Select {...register("userType")}>
<SelectTrigger>Select your role</SelectTrigger>
<SelectContent>
<SelectItem value="private_landlord">
Private landlord
</SelectItem>
<SelectItem value="private_tenant">Private tenant</SelectItem>
<SelectItem value="social_landlord">Social landlord</SelectItem>
<SelectItem value="social_tenant">Social tenant</SelectItem>
<SelectItem value="homeowner">Homeowner</SelectItem>
<SelectItem value="other">Other</SelectItem>
</SelectContent>
</Select>
{(userType === "private_landlord" ||
userType === "social_landlord") && (
<Select {...register("propertyCount")}>
<SelectTrigger>
How many properties do you manage?
</SelectTrigger>
<SelectContent>
{userType === "private_landlord" ? (
<>
<SelectItem value="1">1</SelectItem>
<SelectItem value="25">25</SelectItem>
<SelectItem value="620">620</SelectItem>
<SelectItem value="21+">21+</SelectItem>
</>
) : (
<>
<SelectItem value="150">150</SelectItem>
<SelectItem value="51100">51100</SelectItem>
<SelectItem value="101300">101300</SelectItem>
<SelectItem value="3011000">3011000</SelectItem>
<SelectItem value="1000+">1000+</SelectItem>
</>
)}
</SelectContent>
</Select>
)}
</div>
)}
{step === 2 && (
<div className="space-y-4">
<p className="font-medium text-gray-700">
What are your main goals?
<div className="relative z-10 flex items-start justify-start w-full h-full">
<div className="mt-20 p-20 text-gray-100 shadow-xl w-[75%] rounded-br-[8rem] bg-gradient-to-r from-brandblue to-midblue">
<h2 className="text-5xl font-bold mb-4">Welcome to Domna IQ</h2>
<p className="text-xl leading-relaxed text-brandbrown">
Help us get to know you so we can tailor your experience.
</p>
</div>
</div>
</div>
{/* Right section with journey and form */}
<div className="flex flex-col flex-1 items-center justify-start p-10 mt-8 relative">
{/* Domna Journey Progress */}
<div className="w-full max-w-3xl mt-8 mb-8">
<h3 className="text-center text-brandblue text-xl font-semibold mb-5">
Your retrofit journey with Domna
</h3>
{/* Row 1: Nodes + Connectors */}
<div className="relative flex items-center justify-center w-full">
{[
"access_funding",
"net_zero",
"improve_condition",
"save_money",
"other",
].map((goal) => (
<label key={goal} className="flex items-center space-x-2">
<Checkbox
checked={watch("goals")?.includes(goal)}
onCheckedChange={(checked) => {
const goals = watch("goals") ?? [];
setValue(
"goals",
checked
? [...goals, goal]
: goals.filter((g) => g !== goal)
);
}}
/>
<span className="capitalize">{goal.replace("_", " ")}</span>
</label>
{ label: "Remote Portfolio Assessment", icon: "🧠", step: 1 },
{ label: "Survey & Design", icon: "📐", step: 2 },
{ label: "Installation & Funding Claim", icon: "🏡", step: 3 },
].map((stage, i, arr) => {
const active = step >= stage.step;
const showConnector = i < arr.length - 1;
const segmentFilled = step > stage.step;
return (
<Fragment key={stage.step}>
<div className="flex-none w-[180px] flex flex-col items-center text-center">
<div
className={`flex items-center justify-center w-12 h-12 rounded-full border-2 text-lg font-semibold mb-2 transition-all duration-500 ${
active
? "bg-brandblue text-white border-brandblue shadow-md"
: "bg-white text-gray-400 border-gray-300"
}`}
>
<span>{stage.icon}</span>
</div>
<p
className={`text-sm font-medium max-w-[8rem] ${
active ? "text-brandblue" : "text-gray-400"
}`}
>
{stage.label}
</p>
</div>
{showConnector && (
<div className="flex-none w-[60px] md:w-[80px] relative">
<div className="absolute left-2 right-2 top-[1.5rem] h-[2px] bg-gray-300" />
<div
className={`absolute left-2 top-[1.5rem] h-[2px] transition-all duration-500 ${
segmentFilled
? "right-2 bg-brandblue"
: "w-0 bg-brandblue"
}`}
/>
</div>
)}
</Fragment>
);
})}
</div>
{/* Row 2: Captions aligned under each node */}
<div className="mt-4 grid grid-cols-3 gap-2 text-gray-600 justify-items-center">
{[
{
step: 1,
caption:
"IQ models home energy improvements, costs, and funding availability at the click of a button.",
},
{
step: 2,
caption:
"Schedule a survey. Our team surveys properties and produces a tailored retrofit design.",
},
{
step: 3,
caption:
"We guide installation and help you claim any available funding to complete your retrofit journey.",
},
].map(({ step: s, caption }) => (
<div
key={s}
className={`text-xs leading-snug text-center w-[200px] transition-opacity duration-300 ${
step === s ? "opacity-100" : "opacity-70"
}`}
style={{ minHeight: "3rem" }}
>
{caption}
</div>
))}
</div>
</div>
<Select {...register("referralSource")}>
<SelectTrigger>How did you hear about us?</SelectTrigger>
<SelectContent>
<SelectItem value="search">Search</SelectItem>
<SelectItem value="social_media">Social Media</SelectItem>
<SelectItem value="NRLA">NRLA</SelectItem>
<SelectItem value="partner">Partner</SelectItem>
<SelectItem value="word_of_mouth">Word of mouth</SelectItem>
<SelectItem value="other">Other</SelectItem>
</SelectContent>
</Select>
{referralSource === "NRLA" && (
<Input
{...register("nrlaMembershipId")}
placeholder="Enter your NRLA Membership ID"
{/* Onboarding Form */}
<form
onSubmit={handleSubmit(onSubmit)}
className="w-full max-w-lg bg-white rounded-xl shadow-md p-8 flex flex-col min-h-[400px]"
>
{/* Progress indicator */}
<div className="flex items-center pb-4">
{[1, 2, 3].map((i) => (
<div
key={i}
className={`flex-1 h-1 mx-1 rounded ${
i <= step ? "bg-brandbrown" : "bg-gray-200"
}`}
/>
))}
</div>
<div className="flex-grow space-y-6">
{step === 1 && (
<div className="space-y-4">
<h1 className="text-2xl font-semibold text-brandblue">
Step 1 of 3
</h1>
<Controller
control={control}
name="userType"
render={({ field }) => (
<Select value={field.value} onValueChange={field.onChange}>
<SelectTrigger>
{field.value
? field.value
.replace("_", " ")
.replace(/\b\w/g, (c) => c.toUpperCase())
: "Tell us who you are"}
</SelectTrigger>
<SelectContent>
<SelectItem value="private_landlord">
Im a private landlord
</SelectItem>
<SelectItem value="private_tenant">
Im a private tenant
</SelectItem>
<SelectItem value="social_landlord">
I manage social housing
</SelectItem>
<SelectItem value="social_tenant">
I live in social housing
</SelectItem>
<SelectItem value="homeowner">
I own my own home
</SelectItem>
<SelectItem value="other">Something else</SelectItem>
</SelectContent>
</Select>
)}
/>
{errors.userType && (
<p className="text-sm text-red-500">
{errors.userType.message}
</p>
)}
{(userType === "private_landlord" ||
userType === "social_landlord") && (
<Controller
control={control}
name="propertyCount"
render={({ field }) => (
<Select
value={field.value}
onValueChange={field.onChange}
placeholder="How many properties do you manage?"
>
<SelectTrigger>
{field.value ??
"Please tell us how many properties you're responsible for"}
</SelectTrigger>
<SelectContent>
{userType === "private_landlord" ? (
<>
<SelectItem value="1">1</SelectItem>
<SelectItem value="25">25</SelectItem>
<SelectItem value="620">620</SelectItem>
<SelectItem value="21+">21+</SelectItem>
</>
) : (
<>
<SelectItem value="150">150</SelectItem>
<SelectItem value="51100">51100</SelectItem>
<SelectItem value="101300">101300</SelectItem>
<SelectItem value="3011000">3011000</SelectItem>
<SelectItem value="1000+">1000+</SelectItem>
</>
)}
</SelectContent>
</Select>
)}
/>
)}
</div>
)}
{step === 2 && (
<div className="space-y-4">
<h1 className="text-2xl font-semibold text-brandblue">
Step 2 of 3
</h1>
<p className="font-medium text-gray-700">
What would you like to achieve with Domna?
<span className="text-red-500">*</span>
</p>
<div className="grid grid-cols-2 gap-2">
{[
"access_funding",
"net_zero",
"improve_condition",
"save_money",
"other",
].map((g) => (
<label
key={g}
className="flex items-center space-x-2 cursor-pointer"
>
<Checkbox
checked={watch("goals")?.includes(g)}
onCheckedChange={(checked) => {
const goals = watch("goals") ?? [];
setValue(
"goals",
checked
? [...goals, g]
: goals.filter((gg) => gg !== g)
);
}}
/>
<span className="capitalize">{g.replace("_", " ")}</span>
</label>
))}
</div>
<Controller
control={control}
name="referralSource"
render={({ field }) => (
<Select
value={field.value}
onValueChange={field.onChange}
placeholder="How did you hear about us?"
>
<SelectTrigger>
{field.value ?? "Referral source"}
</SelectTrigger>
<SelectContent>
<SelectItem value="search">Search</SelectItem>
<SelectItem value="social_media">
Social Media
</SelectItem>
<SelectItem value="NRLA">NRLA</SelectItem>
<SelectItem value="partner">Partner</SelectItem>
<SelectItem value="word_of_mouth">
Word of Mouth
</SelectItem>
<SelectItem value="other">Other</SelectItem>
</SelectContent>
</Select>
)}
/>
{referralSource === "NRLA" && (
<Input
{...register("nrlaMembershipId")}
placeholder="Enter your NRLA membership ID"
/>
)}
</div>
)}
{step === 3 && (
<div className="space-y-4">
<h1 className="text-2xl font-semibold text-brandblue">
Step 3 of 3
</h1>
<Input
{...register("firstName")}
placeholder="First name"
required
/>
<Input
{...register("lastName")}
placeholder="Last name"
required
/>
<label className="flex items-center space-x-2">
<Checkbox {...register("acceptedPrivacy")} />
<span className="text-sm">
I agree to the{" "}
<a
href="https://www.domna.homes/privacy"
target="_blank"
rel="noopener noreferrer"
className="text-brandblue underline"
>
Privacy Policy
</a>
</span>
</label>
<label className="flex items-center space-x-2">
<Checkbox {...register("marketingOptIn")} />
<span className="text-sm text-gray-700">
Id like to hear more about funding opportunities, retrofit
schemes, and energy upgrades.
</span>
</label>
</div>
)}
</div>
)}
{step === 3 && (
<div className="space-y-4">
<Input
{...register("firstName")}
placeholder="First name"
required
/>
<Input {...register("lastName")} placeholder="Last name" required />
<label className="flex items-center space-x-2">
<Checkbox {...register("acceptedPrivacy")} />
<span>
I agree to the{" "}
<a href="/privacy" className="text-brandblue underline">
Privacy Policy
</a>
</span>
</label>
<label className="flex items-center space-x-2">
<Checkbox {...register("marketingOptIn")} />
<span>I'd like to receive marketing updates</span>
</label>
{/* Buttons fixed at bottom */}
<div className="flex justify-end pt-4">
{step > 1 && (
<Button
className="bg-brandlightblue mr-2"
variant="outline"
type="button"
onClick={prevStep}
>
Back
</Button>
)}
{step < 3 ? (
<Button
type="button"
className="bg-brandbrown hover:bg-hoverblue"
onClick={nextStep}
>
Next
</Button>
) : (
<Button
type="submit"
className="bg-brandbrown hover:bg-hoverblue"
disabled={!isValid}
>
Finish
</Button>
)}
</div>
)}
<div className="flex justify-between pt-4">
{step > 1 && (
<Button
type="button"
variant="outline"
onClick={() => setStep(step - 1)}
>
Back
</Button>
)}
{step < 3 ? (
<Button type="button" onClick={() => setStep(step + 1)}>
Next
</Button>
) : (
<Button type="submit" className="bg-brandblue hover:bg-hoverblue">
Finish
</Button>
)}
</div>
</form>
</form>
</div>
</div>
);
}

View file

@ -2,14 +2,11 @@
import * as React from "react";
import * as SelectPrimitive from "@radix-ui/react-select";
import { Check, ChevronDown } from "lucide-react";
import { Check, ChevronDown, ChevronUp } from "lucide-react";
import { cn } from "@/lib/utils";
const Select = SelectPrimitive.Root;
const SelectGroup = SelectPrimitive.Group;
const SelectValue = SelectPrimitive.Value;
const SelectTrigger = React.forwardRef<
@ -18,11 +15,11 @@ const SelectTrigger = React.forwardRef<
>(({ className, children, ...props }, ref) => (
<SelectPrimitive.Trigger
ref={ref}
{...props}
className={cn(
"flex h-10 w-full items-center justify-between rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
"flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className
)}
{...props}
>
{children}
<SelectPrimitive.Icon asChild>
@ -32,22 +29,60 @@ const SelectTrigger = React.forwardRef<
));
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
const SelectScrollUpButton = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
>(({ className, ...props }, ref) => (
<SelectPrimitive.ScrollUpButton
ref={ref}
{...props}
className={cn(
"flex cursor-default items-center justify-center py-1",
className
)}
>
<ChevronUp className="h-4 w-4" />
</SelectPrimitive.ScrollUpButton>
));
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
const SelectScrollDownButton = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
>(({ className, ...props }, ref) => (
<SelectPrimitive.ScrollDownButton
ref={ref}
{...props}
className={cn(
"flex cursor-default items-center justify-center py-1",
className
)}
>
<ChevronDown className="h-4 w-4" />
</SelectPrimitive.ScrollDownButton>
));
SelectScrollDownButton.displayName =
SelectPrimitive.ScrollDownButton.displayName;
const SelectContent = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content> & {
position?: "popper" | "item-aligned";
}
>(({ className, children, position = "popper", ...props }, ref) => (
<SelectPrimitive.Portal>
<SelectPrimitive.Content
ref={ref}
{...props}
position={position}
className={cn(
"relative z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
"relative z-50 max-h-[--radix-select-content-available-height] min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
position === "popper" &&
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
className
)}
position={position}
{...props}
>
<SelectScrollUpButton />
<SelectPrimitive.Viewport
className={cn(
"p-1",
@ -57,6 +92,7 @@ const SelectContent = React.forwardRef<
>
{children}
</SelectPrimitive.Viewport>
<SelectScrollDownButton />
</SelectPrimitive.Content>
</SelectPrimitive.Portal>
));
@ -68,8 +104,8 @@ const SelectLabel = React.forwardRef<
>(({ className, ...props }, ref) => (
<SelectPrimitive.Label
ref={ref}
className={cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className)}
{...props}
className={cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className)}
/>
));
SelectLabel.displayName = SelectPrimitive.Label.displayName;
@ -80,18 +116,17 @@ const SelectItem = React.forwardRef<
>(({ className, children, ...props }, ref) => (
<SelectPrimitive.Item
ref={ref}
{...props}
className={cn(
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className
)}
{...props}
>
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<SelectPrimitive.ItemIndicator>
<Check className="h-4 w-4" />
</SelectPrimitive.ItemIndicator>
</span>
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
</SelectPrimitive.Item>
));
@ -103,8 +138,8 @@ const SelectSeparator = React.forwardRef<
>(({ className, ...props }, ref) => (
<SelectPrimitive.Separator
ref={ref}
className={cn("-mx-1 my-1 h-px bg-muted", className)}
{...props}
className={cn("-mx-1 my-1 h-px bg-muted", className)}
/>
));
SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
@ -118,4 +153,6 @@ export {
SelectLabel,
SelectItem,
SelectSeparator,
SelectScrollUpButton,
SelectScrollDownButton,
};

View file

@ -12,227 +12,230 @@ module.exports = {
"./node_modules/@tremor/**/*.{js,ts,jsx,tsx}",
],
theme: {
transparent: 'transparent',
current: 'currentColor',
container: {
center: true,
padding: '2rem',
screens: {
'2xl': '1400px'
}
},
extend: {
backgroundImage: {
'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
'gradient-conic': 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))'
},
colors: {
tremor: {
brand: {
faint: 'colors.blue[50]',
muted: 'colors.blue[200]',
subtle: 'colors.blue[400]',
DEFAULT: 'colors.blue[500]',
emphasis: 'colors.blue[700]',
inverted: 'colors.white'
},
background: {
muted: 'colors.gray[50]',
subtle: 'colors.gray[100]',
DEFAULT: 'colors.white',
emphasis: 'colors.gray[700]'
},
border: {
DEFAULT: 'colors.gray[200]'
},
ring: {
DEFAULT: 'colors.gray[200]'
},
content: {
subtle: 'colors.gray[400]',
DEFAULT: 'colors.gray[500]',
emphasis: 'colors.gray[700]',
strong: 'colors.gray[900]',
inverted: 'colors.white'
}
},
'dark-tremor': {
brand: {
faint: '#0B1229',
muted: 'colors.blue[950]',
subtle: 'colors.blue[800]',
DEFAULT: 'colors.blue[500]',
emphasis: 'colors.blue[400]',
inverted: 'colors.blue[950]'
},
background: {
muted: '#131A2B',
subtle: 'colors.gray[800]',
DEFAULT: 'colors.gray[900]',
emphasis: 'colors.gray[300]'
},
border: {
DEFAULT: 'colors.gray[800]'
},
ring: {
DEFAULT: 'colors.gray[800]'
},
content: {
subtle: 'colors.gray[600]',
DEFAULT: 'colors.gray[500]',
emphasis: 'colors.gray[200]',
strong: 'colors.gray[50]',
inverted: 'colors.gray[950]'
}
},
epc_a: '#117d58',
epc_b: '#2da55c',
epc_c: '#8dbd40',
epc_d: '#f7cd14',
epc_e: '#f3a96a',
epc_f: '#ef8026',
epc_g: '#e41e3b',
brandblue: '#14163d',
hoverblue: '#3e4073',
brandtan: '#d3b488',
hovertan: '#947750',
brandgold: '#f1bb06',
hovergold: '#c79d12',
brandbrown: '#c4a47c',
brandmidblue: '#3943b7',
brandlightblue: '#00a9f4',
border: 'hsl(var(--border))',
input: 'hsl(var(--input))',
ring: 'hsl(var(--ring))',
background: 'hsl(var(--background))',
foreground: 'hsl(var(--foreground))',
primary: {
DEFAULT: 'hsl(var(--primary))',
foreground: 'hsl(var(--primary-foreground))'
},
secondary: {
DEFAULT: 'hsl(var(--secondary))',
foreground: 'hsl(var(--secondary-foreground))'
},
destructive: {
DEFAULT: 'hsl(var(--destructive))',
foreground: 'hsl(var(--destructive-foreground))'
},
muted: {
DEFAULT: 'hsl(var(--muted))',
foreground: 'hsl(var(--muted-foreground))'
},
accent: {
DEFAULT: 'hsl(var(--accent))',
foreground: 'hsl(var(--accent-foreground))'
},
popover: {
DEFAULT: 'hsl(var(--popover))',
foreground: 'hsl(var(--popover-foreground))'
},
card: {
DEFAULT: 'hsl(var(--card))',
foreground: 'hsl(var(--card-foreground))'
}
},
textColor: {
brandblue: '#14163d',
hoverblue: '#3e4073',
brandtan: '#d3b488',
hovertan: '#947750',
brandbrown: '#c4a47c',
brandmidblue: '#3943b7',
brandlightblue: '#00a9f4'
},
borderRadius: {
'tremor-small': '0.375rem',
'tremor-default': '0.5rem',
'tremor-full': '9999px'
},
fontFamily: {
sans: [
'var(--font-sans)',
...fontFamily.sans
]
},
keyframes: {
'accordion-down': {
from: {
height: 0
},
to: {
height: 'var(--radix-accordion-content-height)'
}
},
'accordion-up': {
from: {
height: 'var(--radix-accordion-content-height)'
},
to: {
height: 0
}
},
'accordion-down': {
from: {
height: '0'
},
to: {
height: 'var(--radix-accordion-content-height)'
}
},
'accordion-up': {
from: {
height: 'var(--radix-accordion-content-height)'
},
to: {
height: '0'
}
}
},
animation: {
'accordion-down': 'accordion-down 0.2s ease-out',
'accordion-up': 'accordion-up 0.2s ease-out',
'accordion-down': 'accordion-down 0.2s ease-out',
'accordion-up': 'accordion-up 0.2s ease-out'
},
maxWidth: {
'8xl': '90rem'
},
boxShadow: {
'tremor-input': '0 1px 2px 0 rgb(0 0 0 / 0.05)',
'tremor-card': '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)',
'tremor-dropdown': '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)',
'dark-tremor-input': '0 1px 2px 0 rgb(0 0 0 / 0.05)',
'dark-tremor-card': '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)',
'dark-tremor-dropdown': '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)'
},
fontSize: {
'tremor-label': [
'0.75rem',
{
lineHeight: '1rem'
}
],
'tremor-default': [
'0.875rem',
{
lineHeight: '1.25rem'
}
],
'tremor-title': [
'1.125rem',
{
lineHeight: '1.75rem'
}
],
'tremor-metric': [
'1.875rem',
{
lineHeight: '2.25rem'
}
]
}
}
transparent: "transparent",
current: "currentColor",
container: {
center: true,
padding: "2rem",
screens: {
"2xl": "1400px",
},
},
extend: {
backgroundImage: {
"gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
"gradient-conic":
"conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
},
colors: {
tremor: {
brand: {
faint: "colors.blue[50]",
muted: "colors.blue[200]",
subtle: "colors.blue[400]",
DEFAULT: "colors.blue[500]",
emphasis: "colors.blue[700]",
inverted: "colors.white",
},
background: {
muted: "colors.gray[50]",
subtle: "colors.gray[100]",
DEFAULT: "colors.white",
emphasis: "colors.gray[700]",
},
border: {
DEFAULT: "colors.gray[200]",
},
ring: {
DEFAULT: "colors.gray[200]",
},
content: {
subtle: "colors.gray[400]",
DEFAULT: "colors.gray[500]",
emphasis: "colors.gray[700]",
strong: "colors.gray[900]",
inverted: "colors.white",
},
},
"dark-tremor": {
brand: {
faint: "#0B1229",
muted: "colors.blue[950]",
subtle: "colors.blue[800]",
DEFAULT: "colors.blue[500]",
emphasis: "colors.blue[400]",
inverted: "colors.blue[950]",
},
background: {
muted: "#131A2B",
subtle: "colors.gray[800]",
DEFAULT: "colors.gray[900]",
emphasis: "colors.gray[300]",
},
border: {
DEFAULT: "colors.gray[800]",
},
ring: {
DEFAULT: "colors.gray[800]",
},
content: {
subtle: "colors.gray[600]",
DEFAULT: "colors.gray[500]",
emphasis: "colors.gray[200]",
strong: "colors.gray[50]",
inverted: "colors.gray[950]",
},
},
epc_a: "#117d58",
epc_b: "#2da55c",
epc_c: "#8dbd40",
epc_d: "#f7cd14",
epc_e: "#f3a96a",
epc_f: "#ef8026",
epc_g: "#e41e3b",
brandblue: "#14163d",
hoverblue: "#3e4073",
midblue: "#2d348f",
brandtan: "#d3b488",
hovertan: "#947750",
brandgold: "#f1bb06",
hovergold: "#c79d12",
brandbrown: "#c4a47c",
brandmidblue: "#3943b7",
brandlightblue: "#eff6fc",
border: "hsl(var(--border))",
input: "hsl(var(--input))",
ring: "hsl(var(--ring))",
background: "hsl(var(--background))",
foreground: "hsl(var(--foreground))",
primary: {
DEFAULT: "hsl(var(--primary))",
foreground: "hsl(var(--primary-foreground))",
},
secondary: {
DEFAULT: "hsl(var(--secondary))",
foreground: "hsl(var(--secondary-foreground))",
},
destructive: {
DEFAULT: "hsl(var(--destructive))",
foreground: "hsl(var(--destructive-foreground))",
},
muted: {
DEFAULT: "hsl(var(--muted))",
foreground: "hsl(var(--muted-foreground))",
},
accent: {
DEFAULT: "hsl(var(--accent))",
foreground: "hsl(var(--accent-foreground))",
},
popover: {
DEFAULT: "hsl(var(--popover))",
foreground: "hsl(var(--popover-foreground))",
},
card: {
DEFAULT: "hsl(var(--card))",
foreground: "hsl(var(--card-foreground))",
},
},
textColor: {
brandblue: "#14163d",
hoverblue: "#3e4073",
brandtan: "#d3b488",
hovertan: "#947750",
brandbrown: "#c4a47c",
brandmidblue: "#3943b7",
brandlightblue: "#00a9f4",
},
borderRadius: {
"tremor-small": "0.375rem",
"tremor-default": "0.5rem",
"tremor-full": "9999px",
},
fontFamily: {
sans: ["var(--font-sans)", ...fontFamily.sans],
},
keyframes: {
"accordion-down": {
from: {
height: 0,
},
to: {
height: "var(--radix-accordion-content-height)",
},
},
"accordion-up": {
from: {
height: "var(--radix-accordion-content-height)",
},
to: {
height: 0,
},
},
"accordion-down": {
from: {
height: "0",
},
to: {
height: "var(--radix-accordion-content-height)",
},
},
"accordion-up": {
from: {
height: "var(--radix-accordion-content-height)",
},
to: {
height: "0",
},
},
},
animation: {
"accordion-down": "accordion-down 0.2s ease-out",
"accordion-up": "accordion-up 0.2s ease-out",
"accordion-down": "accordion-down 0.2s ease-out",
"accordion-up": "accordion-up 0.2s ease-out",
},
maxWidth: {
"8xl": "90rem",
},
boxShadow: {
"tremor-input": "0 1px 2px 0 rgb(0 0 0 / 0.05)",
"tremor-card":
"0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
"tremor-dropdown":
"0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
"dark-tremor-input": "0 1px 2px 0 rgb(0 0 0 / 0.05)",
"dark-tremor-card":
"0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
"dark-tremor-dropdown":
"0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
},
fontSize: {
"tremor-label": [
"0.75rem",
{
lineHeight: "1rem",
},
],
"tremor-default": [
"0.875rem",
{
lineHeight: "1.25rem",
},
],
"tremor-title": [
"1.125rem",
{
lineHeight: "1.75rem",
},
],
"tremor-metric": [
"1.875rem",
{
lineHeight: "2.25rem",
},
],
},
},
},
variants: {
extend: {