create-disposabl-app 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +21 -22
- package/dist/templates/default/apps/desktop/.oxfmtrc.json +5 -0
- package/dist/templates/default/apps/desktop/.oxlintrc.json +6 -0
- package/dist/templates/default/apps/desktop/README.md +58 -0
- package/dist/templates/default/apps/desktop/forge.config.mts +90 -0
- package/dist/templates/default/apps/desktop/index.html +12 -0
- package/dist/templates/default/apps/desktop/package.json +55 -1
- package/dist/templates/default/apps/desktop/src/declarations.d.ts +2 -0
- package/dist/templates/default/apps/desktop/src/index.css +8 -0
- package/dist/templates/default/apps/desktop/src/main.ts +58 -0
- package/dist/templates/default/apps/desktop/src/preload.ts +3 -0
- package/dist/templates/default/apps/desktop/src/renderer.ts +19 -0
- package/dist/templates/default/apps/desktop/tsconfig.json +14 -0
- package/dist/templates/default/apps/desktop/vite.main.config.mts +4 -0
- package/dist/templates/default/apps/desktop/vite.preload.config.mts +4 -0
- package/dist/templates/default/apps/desktop/vite.renderer.config.mts +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/agent-device/SKILL.md +22 -0
- package/dist/templates/default/apps/mobile/.agents/skills/android-emulator/SKILL.md +32 -0
- package/dist/templates/default/apps/mobile/.agents/skills/dogfood/SKILL.md +27 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/SKILL.md +176 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/references/app-store-metadata.md +497 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/references/ios-app-store.md +376 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/references/native-ios.md +167 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/references/play-store.md +244 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/references/testflight.md +62 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/references/workflows.md +120 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-hosting/SKILL.md +431 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-hosting/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-observe/SKILL.md +46 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-observe/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-observe/references/metrics.md +98 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-observe/references/queries.md +444 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-observe/references/setup.md +529 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-observe/references/third-party.md +136 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-simulator/SKILL.md +237 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-simulator/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-simulator/references/controllers.md +139 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-simulator/references/logs-and-crashes.md +101 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-simulator/references/run-your-app.md +256 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-simulator/references/troubleshooting.md +56 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-update/SKILL.md +146 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-update/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-update-insights/SKILL.md +238 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-update-insights/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-update-insights/references/channel-insights-schema.md +47 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-update-insights/references/update-insights-schema.md +69 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-workflows/SKILL.md +99 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-workflows/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-workflows/scripts/fetch.js +109 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-workflows/scripts/package.json +6 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-animation/LICENSE +21 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-animation/RECIPES.md +385 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-animation/SKILL.md +274 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-animation/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-app-clip/SKILL.md +290 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-app-clip/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-app-clip/references/native-module.md +96 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/SKILL.md +69 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/references/brownfield-integrated.md +551 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/references/brownfield-isolated.md +449 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/references/comparison.md +63 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/references/feature-integration.md +163 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/references/troubleshooting.md +88 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/references/version-compatibility.md +40 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-data-fetching/SKILL.md +478 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-data-fetching/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-data-fetching/references/expo-router-loaders.md +341 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-data-fetching/references/offline-and-cancellation.md +68 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-design-system/SKILL.md +376 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-design-system/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-design-system/references/audit.md +190 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-design-system/references/native-slop.md +74 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-dev-client/SKILL.md +184 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-dev-client/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-dom/SKILL.md +425 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-dom/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-examples/SKILL.md +106 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-examples/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-examples/references/catalog.md +105 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-migrate-module/SKILL.md +124 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-migrate-module/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-migrate-module/references/compatibility.md +130 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-migrate-module/references/example.md +212 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-migrate-module/references/migration-map.md +457 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-module/SKILL.md +151 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-module/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-module/references/config-plugin.md +90 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-module/references/create-expo-module.md +206 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-module/references/lifecycle.md +127 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-module/references/module-config.md +48 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-module/references/native-module.md +286 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-module/references/native-view.md +171 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/SKILL.md +201 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/references/controls.md +231 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/references/gradients.md +106 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/references/icons.md +232 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/references/media.md +193 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/references/storage.md +121 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/references/visual-effects.md +198 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/references/webgpu-three.md +605 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-overview/SKILL.md +120 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-overview/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-overview/references/launch-without-dev-menu.md +24 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-project-structure/SKILL.md +114 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-project-structure/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-router/SKILL.md +240 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-router/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-router/references/form-sheet.md +253 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-router/references/route-structure.md +229 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-router/references/search.md +248 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-router/references/tabs.md +433 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-router/references/toolbar-and-headers.md +284 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-router/references/zoom-transitions.md +158 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/SKILL.md +314 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/agents/visual-grader.md +52 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/references/design-rubric.md +45 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/references/runtime-matrix.md +34 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/check-static.sh +64 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/clean-fixture.sh +56 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/generate_viewer.py +450 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/latest-sdk.sh +46 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/make-fixture.sh +95 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/make-workspace.sh +31 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/snapshot-android.sh +284 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/snapshot-ios.sh +132 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/snapshot-web.sh +61 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-ui/SKILL.md +101 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-ui/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-ui/references/drop-in-replacements.md +27 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-ui/references/jetpack-compose.md +73 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-ui/references/swift-ui.md +73 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-ui/references/universal.md +104 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-ui/scripts/list-components.js +193 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/SKILL.md +150 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/references/expo-av-to-audio.md +132 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/references/expo-av-to-video.md +160 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/references/native-tabs.md +124 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/references/new-architecture.md +79 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/references/react-19.md +79 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/references/react-compiler.md +59 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/references/react-navigation-to-expo-router.md +61 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-web-to-native/SKILL.md +91 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-web-to-native/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-web-to-native/references/false-friends.md +119 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-web-to-native/references/native-patterns.md +39 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-web-to-native/references/run-as-goal.md +48 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-web-to-native/references/verify-on-device.md +45 -0
- package/dist/templates/default/apps/mobile/.agents/skills/ios-simulator/SKILL.md +32 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/POWER.md +172 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/SKILL.md +238 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-analyze-app.md +208 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-analyze-js.md +264 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-barrel-exports.md +250 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-code-splitting.md +255 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-hermes-mmap.md +167 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-library-size.md +164 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-native-assets.md +208 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-r8-android.md +231 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-tree-shaking.md +215 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/bundle-treemap-source-map-explorer.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/controlled-textinput-pingpong.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/devtools-flamegraph.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/emerge-xray-ios.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/expo-atlas-treemap.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/flashlight-flatlist-vs-flashlist.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/fps-drop-graph.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/memory-heap-snapshot.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/tti-warm-start-diagram.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/view-hierarchy-flattening.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/xcode-instruments-templates.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/xcode-thread-view.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-animations-reanimated.md +273 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-atomic-state.md +190 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-bottomsheet.md +339 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-concurrent-react.md +238 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-lists-flatlist-flashlist.md +223 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-measure-fps.md +178 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-memory-leaks.md +168 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-profile-react.md +138 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-react-compiler.md +261 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-uncontrolled-components.md +219 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-android-16kb-alignment.md +114 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-measure-tti.md +221 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-memory-leaks.md +206 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-memory-patterns.md +240 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-platform-setup.md +112 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-profiling.md +140 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-sdks-over-polyfills.md +192 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-threading-model.md +230 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-turbo-modules.md +210 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-view-flattening.md +180 -0
- package/dist/templates/default/apps/mobile/AGENTS.md +41 -0
- package/dist/templates/default/apps/mobile/app.json +38 -0
- package/dist/templates/default/apps/mobile/assets/expo.icon/Assets/expo-symbol 2.svg +3 -0
- package/dist/templates/default/apps/mobile/assets/expo.icon/Assets/grid.png +0 -0
- package/dist/templates/default/apps/mobile/assets/expo.icon/icon.json +40 -0
- package/dist/templates/default/apps/mobile/assets/images/android-icon-background.png +0 -0
- package/dist/templates/default/apps/mobile/assets/images/android-icon-foreground.png +0 -0
- package/dist/templates/default/apps/mobile/assets/images/android-icon-monochrome.png +0 -0
- package/dist/templates/default/apps/mobile/assets/images/icon.png +0 -0
- package/dist/templates/default/apps/mobile/assets/images/splash-icon.png +0 -0
- package/dist/templates/default/apps/mobile/eslint.config.js +10 -0
- package/dist/templates/default/apps/mobile/package.json +43 -1
- package/dist/templates/default/apps/mobile/skills-lock.json +185 -0
- package/dist/templates/default/apps/mobile/src/app/_layout.tsx +5 -0
- package/dist/templates/default/apps/mobile/src/app/index.tsx +17 -0
- package/dist/templates/default/apps/mobile/tsconfig.json +20 -0
- package/dist/templates/default/apps/web/.agents/skills/frontend-design/SKILL.md +71 -0
- package/dist/templates/default/apps/web/.agents/skills/web-design-guidelines/SKILL.md +39 -0
- package/dist/templates/default/apps/web/.env.example +3 -0
- package/dist/templates/default/apps/web/components.json +23 -0
- package/dist/templates/default/apps/web/eslint.config.ts +21 -0
- package/dist/templates/default/apps/web/package.json +39 -1
- package/dist/templates/default/apps/web/public/disposabl-logo.svg +8 -0
- package/dist/templates/default/apps/web/public/favicon.ico +0 -0
- package/dist/templates/default/apps/web/public/manifest.json +25 -0
- package/dist/templates/default/apps/web/skills-lock.json +17 -0
- package/dist/templates/default/apps/web/src/index.css +92 -0
- package/dist/templates/default/apps/web/src/routeTree.gen.ts +282 -0
- package/dist/templates/default/apps/web/src/router/__root.tsx +63 -0
- package/dist/templates/default/apps/web/src/router/_authenticated/dashboard.tsx +9 -0
- package/dist/templates/default/apps/web/src/router/_authenticated/todos/$id.tsx +27 -0
- package/dist/templates/default/apps/web/src/router/_authenticated/todos/index.tsx +33 -0
- package/dist/templates/default/apps/web/src/router/index.tsx +15 -0
- package/dist/templates/default/apps/web/src/router.tsx +20 -0
- package/dist/templates/default/apps/web/tsconfig.json +33 -0
- package/dist/templates/default/apps/web/tsr.config.json +6 -0
- package/dist/templates/default/apps/web/vite.config.ts +67 -0
- package/dist/templates/default/bun.lock +3932 -0
- package/dist/templates/default/bunfig.toml +5 -0
- package/dist/templates/default/disposabl.json +5 -0
- package/dist/templates/default/gitignore +9 -1
- package/dist/templates/default/package.json +29 -4
- package/dist/templates/default/packages/backend/.agents/skills/convex/SKILL.md +69 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-add/SKILL.md +26 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-advisor/SKILL.md +32 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-agent/SKILL.md +25 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-auth/SKILL.md +29 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-authz/SKILL.md +36 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-backup/SKILL.md +33 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-billing/SKILL.md +69 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-cost/SKILL.md +29 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-create-component/SKILL.md +325 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-create-component/agents/openai.yaml +14 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-create-component/assets/icon.svg +3 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-create-component/references/advanced-patterns.md +146 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-create-component/references/hybrid-components.md +38 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-create-component/references/local-components.md +39 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-create-component/references/packaged-components.md +54 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-crons/SKILL.md +23 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-deploy-guard/SKILL.md +29 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-design/SKILL.md +30 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-docs/SKILL.md +31 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-domains/SKILL.md +26 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-env/SKILL.md +24 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-expert/SKILL.md +38 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-explain-app/SKILL.md +29 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-improve-convex-plugin/SKILL.md +24 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-insights/SKILL.md +32 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-launch-readiness/SKILL.md +35 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-migrate/SKILL.md +23 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-migrate-rehearse/SKILL.md +31 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-monitor/SKILL.md +22 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-optimize/SKILL.md +26 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-quickstart/SKILL.md +29 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-quickstart/agents/openai.yaml +14 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-quickstart/assets/icon.svg +4 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-reviewer/SKILL.md +26 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-seed/SKILL.md +23 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-self-heal/SKILL.md +38 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-sentinel/SKILL.md +25 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-suggest/SKILL.md +27 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-test/SKILL.md +23 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-verify/SKILL.md +34 -0
- package/dist/templates/default/packages/backend/.prettierignore +4 -0
- package/dist/templates/default/packages/backend/AGENTS.md +18 -0
- package/dist/templates/default/packages/backend/CLAUDE.md +13 -0
- package/dist/templates/default/packages/backend/README.md +25 -0
- package/dist/templates/default/packages/backend/convex/_generated/ai/ai-files.state.json +6 -0
- package/dist/templates/default/packages/backend/convex/_generated/ai/guidelines.md +286 -0
- package/dist/templates/default/packages/backend/convex/_generated/api.d.ts +66 -0
- package/dist/templates/default/packages/backend/convex/_generated/api.js +23 -0
- package/dist/templates/default/packages/backend/convex/_generated/dataModel.d.ts +60 -0
- package/dist/templates/default/packages/backend/convex/_generated/server.d.ts +164 -0
- package/dist/templates/default/packages/backend/convex/_generated/server.js +101 -0
- package/dist/templates/default/packages/backend/convex/auth.config.ts +14 -0
- package/dist/templates/default/packages/backend/convex/auth.ts +15 -0
- package/dist/templates/default/packages/backend/convex/convex.config.ts +30 -0
- package/dist/templates/default/packages/backend/convex/http.ts +5 -0
- package/dist/templates/default/packages/backend/convex/mcp.ts +8 -0
- package/dist/templates/default/packages/backend/convex/schema.ts +10 -0
- package/dist/templates/default/packages/backend/convex/todos/index.ts +26 -0
- package/dist/templates/default/packages/backend/convex/todos/internal.ts +43 -0
- package/dist/templates/default/packages/backend/convex/tsconfig.json +27 -0
- package/dist/templates/default/packages/backend/convex/users.ts +20 -0
- package/dist/templates/default/packages/backend/eslint.config.mjs +62 -0
- package/dist/templates/default/packages/backend/package.json +36 -0
- package/dist/templates/default/packages/backend/skills-lock.json +203 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/accordion.tsx +77 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/alert-dialog.tsx +185 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/alert.tsx +75 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/aspect-ratio.tsx +22 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/attachment.tsx +207 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/avatar.tsx +106 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/badge.tsx +51 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/breadcrumb.tsx +121 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/bubble.tsx +127 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/button-group.tsx +87 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/button.tsx +57 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/calendar.tsx +241 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/card.tsx +102 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/carousel.tsx +239 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/chart.tsx +368 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/checkbox.tsx +27 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/code-block.tsx +243 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/collapsible.tsx +19 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/combobox.tsx +300 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/command.tsx +194 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/context-menu.tsx +271 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/dialog.tsx +156 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/direction.tsx +4 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/drawer.tsx +224 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/dropdown-menu.tsx +269 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/empty.tsx +103 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/field.tsx +236 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/hover-card.tsx +50 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/input-group.tsx +158 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/input-otp.tsx +83 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/input.tsx +19 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/item.tsx +201 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/kbd.tsx +26 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/label.tsx +19 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/marker.tsx +70 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/menubar.tsx +284 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/message-scroller.tsx +128 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/message.tsx +91 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/native-select.tsx +64 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/navigation-menu.tsx +170 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/pagination.tsx +133 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/popover.tsx +87 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/progress.tsx +82 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/questionnaire.tsx +330 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/radio-group.tsx +35 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/resizable.tsx +49 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/scroll-area.tsx +51 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/select.tsx +201 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/separator.tsx +22 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/sheet.tsx +132 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/sidebar.tsx +723 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/skeleton.tsx +13 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/slider.tsx +51 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/spinner.tsx +16 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/switch.tsx +31 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/table.tsx +113 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/tabs.tsx +81 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/textarea.tsx +17 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/toast.tsx +229 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/toggle-group.tsx +87 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/toggle.tsx +42 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/tooltip.tsx +65 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/trace.tsx +161 -0
- package/dist/templates/default/packages/disposabl-kit/client/hooks/use-mobile.ts +21 -0
- package/dist/templates/default/packages/disposabl-kit/client/lib/prerender.ts +89 -0
- package/dist/templates/default/packages/disposabl-kit/client/lib/return-to.ts +12 -0
- package/dist/templates/default/packages/disposabl-kit/client/lib/utils.ts +1 -0
- package/dist/templates/default/packages/disposabl-kit/client/routes/_auth-pages/login.tsx +114 -0
- package/dist/templates/default/packages/disposabl-kit/client/routes/_auth-pages/signUp.tsx +120 -0
- package/dist/templates/default/packages/disposabl-kit/client/routes/_authenticated/route.tsx +38 -0
- package/dist/templates/default/packages/disposabl-kit/client/routes/consent.tsx +137 -0
- package/dist/templates/default/packages/disposabl-kit/client/routes/route.tsx +30 -0
- package/dist/templates/default/packages/disposabl-kit/client/styles/globals.css +60 -0
- package/dist/templates/default/packages/disposabl-kit/client/vite.config.ts +32 -0
- package/dist/templates/default/packages/disposabl-kit/components.json +23 -0
- package/dist/templates/default/packages/disposabl-kit/eslint.config.js +21 -0
- package/dist/templates/default/packages/disposabl-kit/package.json +60 -0
- package/dist/templates/default/packages/disposabl-kit/server/http.ts +86 -0
- package/dist/templates/default/packages/disposabl-kit/server/lib/functions.ts +40 -0
- package/dist/templates/default/packages/disposabl-kit/server/lib/platforms.ts +20 -0
- package/dist/templates/default/packages/disposabl-kit/server/lib/static-routes.ts +56 -0
- package/dist/templates/default/packages/disposabl-kit/tsconfig.json +17 -0
- package/dist/templates/default/patches/@convex-dev%2Fauth@2.0.0-beta.0.patch +310 -0
- package/dist/templates/default/patches/@convex-dev%2Fstatic-hosting@0.2.1.patch +187 -0
- package/dist/templates/default/tsconfig.json +9 -0
- package/dist/templates/default/turbo.json +51 -0
- package/package.json +1 -2
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Tooltip as TooltipPrimitive } from "@base-ui/react/tooltip";
|
|
4
|
+
import { cn } from "@disposabl/disposabl-kit/client/lib/utils";
|
|
5
|
+
|
|
6
|
+
function TooltipProvider({
|
|
7
|
+
delay = 0,
|
|
8
|
+
...props
|
|
9
|
+
}: TooltipPrimitive.Provider.Props) {
|
|
10
|
+
return (
|
|
11
|
+
<TooltipPrimitive.Provider
|
|
12
|
+
data-slot="tooltip-provider"
|
|
13
|
+
delay={delay}
|
|
14
|
+
{...props}
|
|
15
|
+
/>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function Tooltip({ ...props }: TooltipPrimitive.Root.Props) {
|
|
20
|
+
return <TooltipPrimitive.Root data-slot="tooltip" {...props} />;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function TooltipTrigger({ ...props }: TooltipPrimitive.Trigger.Props) {
|
|
24
|
+
return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function TooltipContent({
|
|
28
|
+
className,
|
|
29
|
+
side = "top",
|
|
30
|
+
sideOffset = 4,
|
|
31
|
+
align = "center",
|
|
32
|
+
alignOffset = 0,
|
|
33
|
+
children,
|
|
34
|
+
...props
|
|
35
|
+
}: TooltipPrimitive.Popup.Props &
|
|
36
|
+
Pick<
|
|
37
|
+
TooltipPrimitive.Positioner.Props,
|
|
38
|
+
"align" | "alignOffset" | "side" | "sideOffset"
|
|
39
|
+
>) {
|
|
40
|
+
return (
|
|
41
|
+
<TooltipPrimitive.Portal>
|
|
42
|
+
<TooltipPrimitive.Positioner
|
|
43
|
+
align={align}
|
|
44
|
+
alignOffset={alignOffset}
|
|
45
|
+
side={side}
|
|
46
|
+
sideOffset={sideOffset}
|
|
47
|
+
className="isolate z-50"
|
|
48
|
+
>
|
|
49
|
+
<TooltipPrimitive.Popup
|
|
50
|
+
data-slot="tooltip-content"
|
|
51
|
+
className={cn(
|
|
52
|
+
"z-50 inline-flex w-fit max-w-xs origin-(--transform-origin) items-center gap-1.5 rounded-md bg-foreground px-3 py-1.5 text-xs text-background has-data-[slot=kbd]:pr-1.5 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-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 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
|
|
53
|
+
className,
|
|
54
|
+
)}
|
|
55
|
+
{...props}
|
|
56
|
+
>
|
|
57
|
+
{children}
|
|
58
|
+
<TooltipPrimitive.Arrow className="z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground data-[side=bottom]:top-1 data-[side=inline-end]:top-1/2! data-[side=inline-end]:-left-1 data-[side=inline-end]:-translate-y-1/2 data-[side=inline-start]:top-1/2! data-[side=inline-start]:-right-1 data-[side=inline-start]:-translate-y-1/2 data-[side=left]:top-1/2! data-[side=left]:-right-1 data-[side=left]:-translate-y-1/2 data-[side=right]:top-1/2! data-[side=right]:-left-1 data-[side=right]:-translate-y-1/2 data-[side=top]:-bottom-2.5" />
|
|
59
|
+
</TooltipPrimitive.Popup>
|
|
60
|
+
</TooltipPrimitive.Positioner>
|
|
61
|
+
</TooltipPrimitive.Portal>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { cn } from "@disposabl/disposabl-kit/client/lib/utils";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
Collapsible,
|
|
6
|
+
CollapsibleContent,
|
|
7
|
+
CollapsibleTrigger,
|
|
8
|
+
} from "@disposabl/disposabl-kit/client/components/ui/collapsible";
|
|
9
|
+
import { ChevronRightIcon } from "lucide-react";
|
|
10
|
+
|
|
11
|
+
function Trace({ className, ...props }: React.ComponentProps<"div">) {
|
|
12
|
+
return (
|
|
13
|
+
<div
|
|
14
|
+
data-slot="trace"
|
|
15
|
+
className={cn(
|
|
16
|
+
"flex w-full min-w-0 flex-col gap-2 *:has-[>[data-slot=trace-line]]:flex *:has-[>[data-slot=trace-line]]:w-fit *:has-[>[data-slot=trace-line]]:max-w-full *:has-[>[data-slot=trace-line]]:min-w-0 *:has-[>[data-slot=trace-line]]:rounded-md *:has-[>[data-slot=trace-line]]:text-left *:has-[>[data-slot=trace-line]]:outline-none *:has-[>[data-slot=trace-line]]:focus-visible:ring-3 *:has-[>[data-slot=trace-line]]:focus-visible:ring-ring/50",
|
|
17
|
+
className,
|
|
18
|
+
)}
|
|
19
|
+
{...props}
|
|
20
|
+
/>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function TraceLine({
|
|
25
|
+
className,
|
|
26
|
+
status,
|
|
27
|
+
...props
|
|
28
|
+
}: React.ComponentProps<"span"> & {
|
|
29
|
+
status?: "running" | "error" | "pending";
|
|
30
|
+
}) {
|
|
31
|
+
return (
|
|
32
|
+
<span
|
|
33
|
+
data-slot="trace-line"
|
|
34
|
+
data-status={status}
|
|
35
|
+
className={cn(
|
|
36
|
+
"flex w-fit max-w-full min-w-0 items-center gap-2 text-sm text-muted-foreground transition-colors in-[a,button]:cursor-pointer in-[a:hover,button:hover]:text-foreground data-[status=error]:text-destructive data-[status=error]:in-[a:hover,button:hover]:text-destructive data-[status=pending]:opacity-60 data-[status=running]:*:data-[slot=trace-title]:shimmer",
|
|
37
|
+
className,
|
|
38
|
+
)}
|
|
39
|
+
{...props}
|
|
40
|
+
/>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function TraceIcon({ className, ...props }: React.ComponentProps<"span">) {
|
|
45
|
+
return (
|
|
46
|
+
<span
|
|
47
|
+
data-slot="trace-icon"
|
|
48
|
+
aria-hidden="true"
|
|
49
|
+
className={cn(
|
|
50
|
+
"flex size-4 shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [[data-slot=trace-title]~&]:-ml-1",
|
|
51
|
+
className,
|
|
52
|
+
)}
|
|
53
|
+
{...props}
|
|
54
|
+
/>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function TraceTitle({ className, ...props }: React.ComponentProps<"span">) {
|
|
59
|
+
return (
|
|
60
|
+
<span
|
|
61
|
+
data-slot="trace-title"
|
|
62
|
+
className={cn("min-w-0 truncate motion-reduce:shimmer-none", className)}
|
|
63
|
+
{...props}
|
|
64
|
+
/>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function TraceDescription({
|
|
69
|
+
className,
|
|
70
|
+
...props
|
|
71
|
+
}: React.ComponentProps<"span">) {
|
|
72
|
+
return (
|
|
73
|
+
<span
|
|
74
|
+
data-slot="trace-description"
|
|
75
|
+
className={cn(
|
|
76
|
+
"shrink-0 text-muted-foreground/70 tabular-nums",
|
|
77
|
+
className,
|
|
78
|
+
)}
|
|
79
|
+
{...props}
|
|
80
|
+
/>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function TraceCollapsible({
|
|
85
|
+
className,
|
|
86
|
+
...props
|
|
87
|
+
}: Omit<React.ComponentProps<typeof Collapsible>, "open"> &
|
|
88
|
+
(
|
|
89
|
+
| { open?: undefined }
|
|
90
|
+
| {
|
|
91
|
+
open: boolean;
|
|
92
|
+
onOpenChange: NonNullable<
|
|
93
|
+
React.ComponentProps<typeof Collapsible>["onOpenChange"]
|
|
94
|
+
>;
|
|
95
|
+
}
|
|
96
|
+
)) {
|
|
97
|
+
return (
|
|
98
|
+
<Collapsible
|
|
99
|
+
data-slot="trace-collapsible"
|
|
100
|
+
className={cn("flex w-full min-w-0 flex-col", className)}
|
|
101
|
+
{...props}
|
|
102
|
+
/>
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function TraceCollapsibleTrigger({
|
|
107
|
+
className,
|
|
108
|
+
children,
|
|
109
|
+
...props
|
|
110
|
+
}: React.ComponentProps<typeof CollapsibleTrigger>) {
|
|
111
|
+
return (
|
|
112
|
+
<CollapsibleTrigger
|
|
113
|
+
data-slot="trace-collapsible-trigger"
|
|
114
|
+
className={cn(
|
|
115
|
+
"group/trace-collapsible-trigger flex w-fit max-w-full min-w-0 cursor-pointer items-center gap-1 rounded-md text-left text-muted-foreground transition-colors outline-none hover:text-foreground focus-visible:ring-3 focus-visible:ring-ring/50 has-[[data-status=error]]:text-destructive",
|
|
116
|
+
className,
|
|
117
|
+
)}
|
|
118
|
+
{...props}
|
|
119
|
+
>
|
|
120
|
+
{children}
|
|
121
|
+
<TraceIcon className="transition-transform group-aria-expanded/trace-collapsible-trigger:rotate-90">
|
|
122
|
+
<ChevronRightIcon />
|
|
123
|
+
</TraceIcon>
|
|
124
|
+
</CollapsibleTrigger>
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function TraceCollapsibleContent({
|
|
129
|
+
className,
|
|
130
|
+
children,
|
|
131
|
+
...props
|
|
132
|
+
}: React.ComponentProps<typeof CollapsibleContent>) {
|
|
133
|
+
return (
|
|
134
|
+
<CollapsibleContent
|
|
135
|
+
data-slot="trace-collapsible-content"
|
|
136
|
+
className="h-(--collapsible-panel-height) min-w-0 overflow-hidden transition-[height] duration-200 data-ending-style:h-0 data-starting-style:h-0"
|
|
137
|
+
{...props}
|
|
138
|
+
>
|
|
139
|
+
<div
|
|
140
|
+
data-slot="trace-collapsible-content-inner"
|
|
141
|
+
className={cn(
|
|
142
|
+
"mt-2 mb-1 ml-[calc(--spacing(2)-1px)] min-w-0 border-l pr-1 pl-4 leading-relaxed wrap-break-word text-muted-foreground",
|
|
143
|
+
className,
|
|
144
|
+
)}
|
|
145
|
+
>
|
|
146
|
+
{children}
|
|
147
|
+
</div>
|
|
148
|
+
</CollapsibleContent>
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export {
|
|
153
|
+
Trace,
|
|
154
|
+
TraceLine,
|
|
155
|
+
TraceIcon,
|
|
156
|
+
TraceTitle,
|
|
157
|
+
TraceDescription,
|
|
158
|
+
TraceCollapsible,
|
|
159
|
+
TraceCollapsibleTrigger,
|
|
160
|
+
TraceCollapsibleContent,
|
|
161
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
const MOBILE_BREAKPOINT = 768;
|
|
4
|
+
|
|
5
|
+
export function useIsMobile() {
|
|
6
|
+
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(
|
|
7
|
+
undefined,
|
|
8
|
+
);
|
|
9
|
+
|
|
10
|
+
React.useEffect(() => {
|
|
11
|
+
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
|
|
12
|
+
const onChange = () => {
|
|
13
|
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
14
|
+
};
|
|
15
|
+
mql.addEventListener("change", onChange);
|
|
16
|
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
17
|
+
return () => mql.removeEventListener("change", onChange);
|
|
18
|
+
}, []);
|
|
19
|
+
|
|
20
|
+
return !!isMobile;
|
|
21
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import {
|
|
4
|
+
createRootRoute,
|
|
5
|
+
createRoute,
|
|
6
|
+
createRouter,
|
|
7
|
+
} from "@tanstack/react-router";
|
|
8
|
+
import ts from "typescript";
|
|
9
|
+
|
|
10
|
+
/** Read route metadata without executing route components in the Vite config. */
|
|
11
|
+
function routeMatcher(source: string) {
|
|
12
|
+
const root = createRootRoute();
|
|
13
|
+
const paths = new Map<string, boolean>();
|
|
14
|
+
const file = ts.createSourceFile("routes.ts", source, ts.ScriptTarget.Latest);
|
|
15
|
+
|
|
16
|
+
function visit(node: ts.Node) {
|
|
17
|
+
if (
|
|
18
|
+
ts.isInterfaceDeclaration(node) &&
|
|
19
|
+
node.name.text === "FileRoutesByPath"
|
|
20
|
+
) {
|
|
21
|
+
for (const member of node.members) {
|
|
22
|
+
if (
|
|
23
|
+
!ts.isPropertySignature(member) ||
|
|
24
|
+
!member.type ||
|
|
25
|
+
!ts.isTypeLiteralNode(member.type)
|
|
26
|
+
)
|
|
27
|
+
continue;
|
|
28
|
+
const fields = new Map<string, string>();
|
|
29
|
+
for (const field of member.type.members) {
|
|
30
|
+
if (
|
|
31
|
+
ts.isPropertySignature(field) &&
|
|
32
|
+
ts.isIdentifier(field.name) &&
|
|
33
|
+
field.type &&
|
|
34
|
+
ts.isLiteralTypeNode(field.type) &&
|
|
35
|
+
ts.isStringLiteral(field.type.literal)
|
|
36
|
+
) {
|
|
37
|
+
fields.set(field.name.text, field.type.literal.text);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const id = fields.get("id");
|
|
41
|
+
const fullPath = fields.get("fullPath");
|
|
42
|
+
// Pathless layouts share their parent's URL; only match actual pages.
|
|
43
|
+
if (id && fullPath && fields.get("path")) {
|
|
44
|
+
paths.set(fullPath, id.split("/").includes("_authenticated"));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
ts.forEachChild(node, visit);
|
|
49
|
+
}
|
|
50
|
+
visit(file);
|
|
51
|
+
if (paths.size === 0)
|
|
52
|
+
throw new Error(
|
|
53
|
+
"No page routes found in the generated TanStack route tree.",
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
const router = createRouter({
|
|
57
|
+
routeTree: root.addChildren(
|
|
58
|
+
[...paths.keys()].map((path) =>
|
|
59
|
+
createRoute({ getParentRoute: () => root, path }),
|
|
60
|
+
),
|
|
61
|
+
),
|
|
62
|
+
});
|
|
63
|
+
return (pathname: string) => {
|
|
64
|
+
const matches = router.matchRoutes(pathname);
|
|
65
|
+
const leaf = matches[matches.length - 1];
|
|
66
|
+
return leaf ? paths.get(leaf.fullPath) === true : false;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** The authenticated layout is the single source of protected route membership. */
|
|
71
|
+
export function createPrerenderFilter(
|
|
72
|
+
routeTreeFile = resolve("src/routeTree.gen.ts"),
|
|
73
|
+
) {
|
|
74
|
+
let source: string | undefined;
|
|
75
|
+
let isAuthenticated: ReturnType<typeof routeMatcher> | undefined;
|
|
76
|
+
return (page: { path: string; sitemap?: { exclude?: boolean } }) => {
|
|
77
|
+
// Read lazily: Start generates the route tree after loading the Vite config.
|
|
78
|
+
const nextSource = readFileSync(routeTreeFile, "utf8");
|
|
79
|
+
if (nextSource !== source) {
|
|
80
|
+
isAuthenticated = routeMatcher(nextSource);
|
|
81
|
+
source = nextSource;
|
|
82
|
+
}
|
|
83
|
+
const authenticated = isAuthenticated!(
|
|
84
|
+
new URL(page.path, "http://localhost").pathname,
|
|
85
|
+
);
|
|
86
|
+
if (authenticated) page.sitemap = { ...page.sitemap, exclude: true };
|
|
87
|
+
return !authenticated;
|
|
88
|
+
};
|
|
89
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Allow local destinations only, including their query string and fragment. */
|
|
2
|
+
export function getReturnTo(value: unknown): string | undefined {
|
|
3
|
+
if (typeof value !== "string" || !value.startsWith("/")) return;
|
|
4
|
+
const origin = "https://disposabl.invalid";
|
|
5
|
+
try {
|
|
6
|
+
const url = new URL(value, origin);
|
|
7
|
+
if (url.origin !== origin) return;
|
|
8
|
+
return `${url.pathname}${url.search}${url.hash}`;
|
|
9
|
+
} catch {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { cn } from "cn";
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { createFileRoute, Link, useNavigate } from "@tanstack/react-router";
|
|
2
|
+
import { useSignInWithUsernamePassword } from "@convex-dev/auth/methods/username-password/react";
|
|
3
|
+
import { api } from "../../../../backend/convex/_generated/api";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
import { getReturnTo } from "../../lib/return-to";
|
|
6
|
+
|
|
7
|
+
export function LogIn() {
|
|
8
|
+
const { request, returnTo } = Route.useSearch();
|
|
9
|
+
const navigate = useNavigate();
|
|
10
|
+
const { signIn, pending } = useSignInWithUsernamePassword(api.auth);
|
|
11
|
+
const [username, setUsername] = useState("");
|
|
12
|
+
const [password, setPassword] = useState("");
|
|
13
|
+
const [error, setError] = useState<string | null>(null);
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<>
|
|
17
|
+
<form
|
|
18
|
+
onSubmit={async (e) => {
|
|
19
|
+
e.preventDefault();
|
|
20
|
+
setError(null);
|
|
21
|
+
const result = await signIn({ username, password });
|
|
22
|
+
if (result.status === "complete") {
|
|
23
|
+
if (request)
|
|
24
|
+
await navigate({ to: "/consent", search: { request } });
|
|
25
|
+
else if (returnTo) window.location.assign(returnTo);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
setError(() => {
|
|
29
|
+
switch (result.userError.error) {
|
|
30
|
+
case "USER_NOT_FOUND":
|
|
31
|
+
return "No account exists with that username.";
|
|
32
|
+
case "INVALID_CREDENTIALS":
|
|
33
|
+
return "Incorrect username or password.";
|
|
34
|
+
case "PASSWORD_TOO_SHORT":
|
|
35
|
+
return `Password must be at least ${result.userError.minimumLength} characters.`;
|
|
36
|
+
case "PASSWORD_TOO_LONG":
|
|
37
|
+
return `Password must be at most ${result.userError.maximumLength} characters.`;
|
|
38
|
+
case "PASSWORD_HAS_SURROUNDING_WHITESPACE":
|
|
39
|
+
return "Password can't start or end with whitespace.";
|
|
40
|
+
case "RATE_LIMITED":
|
|
41
|
+
return `Too many attempts. Try again in ${Math.ceil(result.userError.retryAfterMs / 1000)} seconds.`;
|
|
42
|
+
case "OTHER_ERROR":
|
|
43
|
+
// The mutation threw unexpectedly; the original error is
|
|
44
|
+
// available on `cause` if you want to log or inspect it.
|
|
45
|
+
console.error("Sign-in failed:", result.userError.cause);
|
|
46
|
+
return "Something went wrong. Please try again.";
|
|
47
|
+
default:
|
|
48
|
+
result.userError satisfies never;
|
|
49
|
+
console.error("Sign-in failed:", result.userError);
|
|
50
|
+
return "Something went wrong. Please try again.";
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}}
|
|
54
|
+
>
|
|
55
|
+
<h1>Log in</h1>
|
|
56
|
+
<label htmlFor="username">
|
|
57
|
+
Username
|
|
58
|
+
<input
|
|
59
|
+
// Using a static id to help password managers behave correctly
|
|
60
|
+
id="username"
|
|
61
|
+
name="username"
|
|
62
|
+
type="text"
|
|
63
|
+
value={username}
|
|
64
|
+
onChange={(e) => setUsername(e.target.value)}
|
|
65
|
+
autoComplete="username"
|
|
66
|
+
required
|
|
67
|
+
disabled={pending}
|
|
68
|
+
/>
|
|
69
|
+
</label>
|
|
70
|
+
<label htmlFor="password">
|
|
71
|
+
Password
|
|
72
|
+
<input
|
|
73
|
+
// Using a static id to help password managers behave correctly
|
|
74
|
+
id="password"
|
|
75
|
+
name="password"
|
|
76
|
+
type="password"
|
|
77
|
+
value={password}
|
|
78
|
+
onChange={(e) => setPassword(e.target.value)}
|
|
79
|
+
autoComplete="current-password"
|
|
80
|
+
required
|
|
81
|
+
disabled={pending}
|
|
82
|
+
/>
|
|
83
|
+
</label>
|
|
84
|
+
{error ? (
|
|
85
|
+
<p role="alert">
|
|
86
|
+
<strong>{error}</strong>
|
|
87
|
+
</p>
|
|
88
|
+
) : null}
|
|
89
|
+
<button type="submit" disabled={pending}>
|
|
90
|
+
{pending ? "Logging in…" : "Log in"}
|
|
91
|
+
</button>
|
|
92
|
+
</form>
|
|
93
|
+
<p>
|
|
94
|
+
Don't have an account?{" "}
|
|
95
|
+
<Link to="/signup" search={{ request, returnTo }}>
|
|
96
|
+
Sign up
|
|
97
|
+
</Link>
|
|
98
|
+
</p>
|
|
99
|
+
</>
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export const Route = createFileRoute("/_providers/login")({
|
|
104
|
+
validateSearch: (
|
|
105
|
+
search: Record<string, unknown>,
|
|
106
|
+
): { request?: string; returnTo?: string } => ({
|
|
107
|
+
returnTo: getReturnTo(search.returnTo),
|
|
108
|
+
request:
|
|
109
|
+
typeof search.request === "string"
|
|
110
|
+
? search.request.trim() || undefined
|
|
111
|
+
: undefined,
|
|
112
|
+
}),
|
|
113
|
+
component: LogIn,
|
|
114
|
+
});
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { createFileRoute, Link, useNavigate } from "@tanstack/react-router";
|
|
2
|
+
import { DEFAULT_MIN_PASSWORD_LENGTH } from "@convex-dev/auth/methods/username-password";
|
|
3
|
+
import { useSignUpWithUsernamePassword } from "@convex-dev/auth/methods/username-password/react";
|
|
4
|
+
import { api } from "../../../../backend/convex/_generated/api";
|
|
5
|
+
import { useState } from "react";
|
|
6
|
+
import { getReturnTo } from "../../lib/return-to";
|
|
7
|
+
|
|
8
|
+
export function SignUp() {
|
|
9
|
+
const { request, returnTo } = Route.useSearch();
|
|
10
|
+
const navigate = useNavigate();
|
|
11
|
+
const { signUp, pending } = useSignUpWithUsernamePassword(api.auth);
|
|
12
|
+
const [username, setUsername] = useState("");
|
|
13
|
+
const [password, setPassword] = useState("");
|
|
14
|
+
const [error, setError] = useState<string | null>(null);
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<>
|
|
18
|
+
<form
|
|
19
|
+
onSubmit={async (e) => {
|
|
20
|
+
e.preventDefault();
|
|
21
|
+
setError(null);
|
|
22
|
+
const result = await signUp({ username, password });
|
|
23
|
+
if (result.status === "complete") {
|
|
24
|
+
if (request)
|
|
25
|
+
await navigate({ to: "/consent", search: { request } });
|
|
26
|
+
else if (returnTo) window.location.assign(returnTo);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
setError(() => {
|
|
30
|
+
switch (result.userError.error) {
|
|
31
|
+
case "USERNAME_TAKEN":
|
|
32
|
+
return "That username is already taken.";
|
|
33
|
+
case "USERNAME_TOO_SHORT":
|
|
34
|
+
return `Username must be at least ${result.userError.minimumLength} characters.`;
|
|
35
|
+
case "USERNAME_HAS_SURROUNDING_WHITESPACE":
|
|
36
|
+
return "Username can't start or end with whitespace.";
|
|
37
|
+
case "USERNAME_HAS_INVALID_CHARACTERS":
|
|
38
|
+
return "Username contains characters that aren't allowed.";
|
|
39
|
+
case "PASSWORD_TOO_SHORT":
|
|
40
|
+
return `Password must be at least ${result.userError.minimumLength} characters.`;
|
|
41
|
+
case "PASSWORD_TOO_LONG":
|
|
42
|
+
return `Password must be at most ${result.userError.maximumLength} characters.`;
|
|
43
|
+
case "PASSWORD_HAS_SURROUNDING_WHITESPACE":
|
|
44
|
+
return "Password can't start or end with whitespace.";
|
|
45
|
+
case "PASSWORD_TOO_COMMON":
|
|
46
|
+
return "This password is one of the most commonly used passwords. Please choose a different one.";
|
|
47
|
+
case "OTHER_ERROR":
|
|
48
|
+
// The mutation threw unexpectedly; the original error is
|
|
49
|
+
// available on `cause` if you want to log or inspect it.
|
|
50
|
+
console.error("Sign-up failed:", result.userError.cause);
|
|
51
|
+
return "Something went wrong. Please try again.";
|
|
52
|
+
default:
|
|
53
|
+
result.userError satisfies never;
|
|
54
|
+
console.error("Sign-up failed:", result.userError);
|
|
55
|
+
return "Something went wrong. Please try again.";
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}}
|
|
59
|
+
>
|
|
60
|
+
<h1>Sign up</h1>
|
|
61
|
+
<label htmlFor="username">
|
|
62
|
+
Username
|
|
63
|
+
<input
|
|
64
|
+
// Using a static id to help password managers behave correctly
|
|
65
|
+
id="username"
|
|
66
|
+
name="username"
|
|
67
|
+
type="text"
|
|
68
|
+
value={username}
|
|
69
|
+
onChange={(e) => setUsername(e.target.value)}
|
|
70
|
+
autoComplete="username"
|
|
71
|
+
required
|
|
72
|
+
disabled={pending}
|
|
73
|
+
/>
|
|
74
|
+
</label>
|
|
75
|
+
<label htmlFor="password">
|
|
76
|
+
Password
|
|
77
|
+
<input
|
|
78
|
+
// Using a static id to help password managers behave correctly
|
|
79
|
+
id="password"
|
|
80
|
+
name="password"
|
|
81
|
+
type="password"
|
|
82
|
+
value={password}
|
|
83
|
+
onChange={(e) => setPassword(e.target.value)}
|
|
84
|
+
autoComplete="new-password"
|
|
85
|
+
minLength={DEFAULT_MIN_PASSWORD_LENGTH}
|
|
86
|
+
required
|
|
87
|
+
disabled={pending}
|
|
88
|
+
/>
|
|
89
|
+
</label>
|
|
90
|
+
{error ? (
|
|
91
|
+
<p role="alert">
|
|
92
|
+
<strong>{error}</strong>
|
|
93
|
+
</p>
|
|
94
|
+
) : null}
|
|
95
|
+
<button type="submit" disabled={pending}>
|
|
96
|
+
{pending ? "Creating account…" : "Create account"}
|
|
97
|
+
</button>
|
|
98
|
+
</form>
|
|
99
|
+
<p>
|
|
100
|
+
Already have an account?{" "}
|
|
101
|
+
<Link to="/login" search={{ request, returnTo }}>
|
|
102
|
+
Log in
|
|
103
|
+
</Link>
|
|
104
|
+
</p>
|
|
105
|
+
</>
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export const Route = createFileRoute("/_providers/signup")({
|
|
110
|
+
validateSearch: (
|
|
111
|
+
search: Record<string, unknown>,
|
|
112
|
+
): { request?: string; returnTo?: string } => ({
|
|
113
|
+
returnTo: getReturnTo(search.returnTo),
|
|
114
|
+
request:
|
|
115
|
+
typeof search.request === "string"
|
|
116
|
+
? search.request.trim() || undefined
|
|
117
|
+
: undefined,
|
|
118
|
+
}),
|
|
119
|
+
component: SignUp,
|
|
120
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createFileRoute,
|
|
3
|
+
Navigate,
|
|
4
|
+
Outlet,
|
|
5
|
+
useRouterState,
|
|
6
|
+
} from "@tanstack/react-router";
|
|
7
|
+
import { Authenticated, AuthLoading, Unauthenticated } from "convex/react";
|
|
8
|
+
import { useState } from "react";
|
|
9
|
+
import { Spinner } from "../../components/ui/spinner";
|
|
10
|
+
|
|
11
|
+
export const Route = createFileRoute("/_providers/_authenticated")({
|
|
12
|
+
ssr: false,
|
|
13
|
+
head: () => ({ meta: [{ name: "robots", content: "noindex, nofollow" }] }),
|
|
14
|
+
component: function AuthenticatedLayout() {
|
|
15
|
+
return (
|
|
16
|
+
<>
|
|
17
|
+
<Authenticated>
|
|
18
|
+
<Outlet />
|
|
19
|
+
</Authenticated>
|
|
20
|
+
<Unauthenticated>
|
|
21
|
+
<SignInRedirect />
|
|
22
|
+
</Unauthenticated>
|
|
23
|
+
<AuthLoading>
|
|
24
|
+
<Spinner className="h-10 w-10 animate-spin" />
|
|
25
|
+
</AuthLoading>
|
|
26
|
+
</>
|
|
27
|
+
);
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
function SignInRedirect() {
|
|
32
|
+
const href = useRouterState({
|
|
33
|
+
select: (state) => state.location.href,
|
|
34
|
+
});
|
|
35
|
+
// Keep the destination stable while navigating away from the protected route.
|
|
36
|
+
const [returnTo] = useState(href);
|
|
37
|
+
return <Navigate to="/login" search={{ returnTo }} />;
|
|
38
|
+
}
|