Working react-router for default templates (default, tailwind, shadcn); Update Github Action for router='none'
5ac09fcc
18 file(s) · +230 −7
| 18 | 18 | - template: "default" |
|
| 19 | 19 | rpc: true |
|
| 20 | 20 | tanstackQuery: false |
|
| 21 | + | router: "none" |
|
| 21 | 22 | linter: "eslint" |
|
| 22 | 23 | test_name: "Default + RPC + No TanStack Query + ESLint" |
|
| 23 | 24 | - template: "default" |
|
| 24 | 25 | rpc: true |
|
| 25 | 26 | tanstackQuery: false |
|
| 27 | + | router: "none" |
|
| 26 | 28 | linter: "biome" |
|
| 27 | 29 | test_name: "Default + RPC + No TanStack Query + Biome" |
|
| 28 | 30 | - template: "default" |
|
| 29 | 31 | rpc: false |
|
| 30 | 32 | tanstackQuery: false |
|
| 33 | + | router: "none" |
|
| 31 | 34 | linter: "eslint" |
|
| 32 | 35 | test_name: "Default + No RPC + No TanStack Query + ESLint" |
|
| 33 | 36 | - template: "default" |
|
| 34 | 37 | rpc: false |
|
| 35 | 38 | tanstackQuery: false |
|
| 39 | + | router: "none" |
|
| 36 | 40 | linter: "biome" |
|
| 37 | 41 | test_name: "Default + No RPC + No TanStack Query + Biome" |
|
| 38 | 42 | - template: "default" |
|
| 39 | 43 | rpc: true |
|
| 40 | 44 | tanstackQuery: true |
|
| 45 | + | router: "none" |
|
| 41 | 46 | linter: "eslint" |
|
| 42 | 47 | test_name: "Default + RPC + TanStack Query + ESLint" |
|
| 43 | 48 | - template: "default" |
|
| 44 | 49 | rpc: true |
|
| 45 | 50 | tanstackQuery: true |
|
| 51 | + | router: "none" |
|
| 46 | 52 | linter: "biome" |
|
| 47 | 53 | test_name: "Default + RPC + TanStack Query + Biome" |
|
| 48 | 54 | - template: "default" |
|
| 49 | 55 | rpc: false |
|
| 50 | 56 | tanstackQuery: true |
|
| 57 | + | router: "none" |
|
| 51 | 58 | linter: "eslint" |
|
| 52 | 59 | test_name: "Default + No RPC + TanStack Query + ESLint" |
|
| 53 | 60 | - template: "default" |
|
| 54 | 61 | rpc: false |
|
| 55 | 62 | tanstackQuery: true |
|
| 63 | + | router: "none" |
|
| 56 | 64 | linter: "biome" |
|
| 57 | 65 | test_name: "Default + No RPC + TanStack Query + Biome" |
|
| 58 | 66 | ||
| 60 | 68 | - template: "tailwind" |
|
| 61 | 69 | rpc: true |
|
| 62 | 70 | tanstackQuery: false |
|
| 71 | + | router: "none" |
|
| 63 | 72 | linter: "eslint" |
|
| 64 | 73 | test_name: "Tailwind + RPC + No TanStack Query + ESLint" |
|
| 65 | 74 | - template: "tailwind" |
|
| 66 | 75 | rpc: true |
|
| 67 | 76 | tanstackQuery: false |
|
| 77 | + | router: "none" |
|
| 68 | 78 | linter: "biome" |
|
| 69 | 79 | test_name: "Tailwind + RPC + No TanStack Query + Biome" |
|
| 70 | 80 | - template: "tailwind" |
|
| 71 | 81 | rpc: false |
|
| 72 | 82 | tanstackQuery: false |
|
| 83 | + | router: "none" |
|
| 73 | 84 | linter: "eslint" |
|
| 74 | 85 | test_name: "Tailwind + No RPC + No TanStack Query + ESLint" |
|
| 75 | 86 | - template: "tailwind" |
|
| 76 | 87 | rpc: false |
|
| 77 | 88 | tanstackQuery: false |
|
| 89 | + | router: "none" |
|
| 78 | 90 | linter: "biome" |
|
| 79 | 91 | test_name: "Tailwind + No RPC + No TanStack Query + Biome" |
|
| 80 | 92 | - template: "tailwind" |
|
| 81 | 93 | rpc: true |
|
| 82 | 94 | tanstackQuery: true |
|
| 95 | + | router: "none" |
|
| 83 | 96 | linter: "eslint" |
|
| 84 | 97 | test_name: "Tailwind + RPC + TanStack Query + ESLint" |
|
| 85 | 98 | - template: "tailwind" |
|
| 86 | 99 | rpc: true |
|
| 87 | 100 | tanstackQuery: true |
|
| 101 | + | router: "none" |
|
| 88 | 102 | linter: "biome" |
|
| 89 | 103 | test_name: "Tailwind + RPC + TanStack Query + Biome" |
|
| 90 | 104 | - template: "tailwind" |
|
| 91 | 105 | rpc: false |
|
| 92 | 106 | tanstackQuery: true |
|
| 107 | + | router: "none" |
|
| 93 | 108 | linter: "eslint" |
|
| 94 | 109 | test_name: "Tailwind + No RPC + TanStack Query + ESLint" |
|
| 95 | 110 | - template: "tailwind" |
|
| 96 | 111 | rpc: false |
|
| 97 | 112 | tanstackQuery: true |
|
| 113 | + | router: "none" |
|
| 98 | 114 | linter: "biome" |
|
| 99 | 115 | test_name: "Tailwind + No RPC + TanStack Query + Biome" |
|
| 100 | 116 | ||
| 102 | 118 | - template: "shadcn" |
|
| 103 | 119 | rpc: true |
|
| 104 | 120 | tanstackQuery: false |
|
| 121 | + | router: "none" |
|
| 105 | 122 | linter: "eslint" |
|
| 106 | 123 | test_name: "Shadcn + RPC + No TanStack Query + ESLint" |
|
| 107 | 124 | - template: "shadcn" |
|
| 108 | 125 | rpc: true |
|
| 109 | 126 | tanstackQuery: false |
|
| 127 | + | router: "none" |
|
| 110 | 128 | linter: "biome" |
|
| 111 | 129 | test_name: "Shadcn + RPC + No TanStack Query + Biome" |
|
| 112 | 130 | - template: "shadcn" |
|
| 113 | 131 | rpc: false |
|
| 114 | 132 | tanstackQuery: false |
|
| 133 | + | router: "none" |
|
| 134 | + | router: "none" |
|
| 115 | 135 | linter: "eslint" |
|
| 116 | 136 | test_name: "Shadcn + No RPC + No TanStack Query + ESLint" |
|
| 117 | 137 | - template: "shadcn" |
|
| 118 | 138 | rpc: false |
|
| 119 | 139 | tanstackQuery: false |
|
| 140 | + | router: "none" |
|
| 120 | 141 | linter: "biome" |
|
| 121 | 142 | test_name: "Shadcn + No RPC + No TanStack Query + Biome" |
|
| 122 | 143 | - template: "shadcn" |
|
| 123 | 144 | rpc: true |
|
| 124 | 145 | tanstackQuery: true |
|
| 146 | + | router: "none" |
|
| 125 | 147 | linter: "eslint" |
|
| 126 | 148 | test_name: "Shadcn + RPC + TanStack Query + ESLint" |
|
| 127 | 149 | - template: "shadcn" |
|
| 128 | 150 | rpc: true |
|
| 129 | 151 | tanstackQuery: true |
|
| 152 | + | router: "none" |
|
| 130 | 153 | linter: "biome" |
|
| 131 | 154 | test_name: "Shadcn + RPC + TanStack Query + Biome" |
|
| 132 | 155 | - template: "shadcn" |
|
| 133 | 156 | rpc: false |
|
| 134 | 157 | tanstackQuery: true |
|
| 158 | + | router: "none" |
|
| 135 | 159 | linter: "eslint" |
|
| 136 | 160 | test_name: "Shadcn + No RPC + TanStack Query + ESLint" |
|
| 137 | 161 | - template: "shadcn" |
|
| 138 | 162 | rpc: false |
|
| 139 | 163 | tanstackQuery: true |
|
| 164 | + | router: "none" |
|
| 140 | 165 | linter: "biome" |
|
| 141 | 166 | test_name: "Shadcn + No RPC + TanStack Query + Biome" |
|
| 142 | 167 | ||
| 26 | 26 | projectName, |
|
| 27 | 27 | }); |
|
| 28 | 28 | ||
| 29 | - | const selectedTemplate = nameGenerator("App.tsx", { |
|
| 30 | - | rpc, |
|
| 31 | - | shadcn, |
|
| 32 | - | tailwind, |
|
| 33 | - | tanstackQuery, |
|
| 29 | + | const appTsxTemplate = nameGenerator("App.tsx", { |
|
| 34 | 30 | reactRouter: true, |
|
| 35 | 31 | }); |
|
| 36 | 32 | ||
| 39 | 35 | "client", |
|
| 40 | 36 | "src", |
|
| 41 | 37 | "App.tsx", |
|
| 42 | - | selectedTemplate, |
|
| 38 | + | appTsxTemplate, |
|
| 43 | 39 | ); |
|
| 44 | 40 | const appTsxTarget = path.join(projectPath, "client", "src", "App.tsx"); |
|
| 45 | 41 | fs.copySync(appTsxSrc, appTsxTarget); |
|
| 42 | + | ||
| 43 | + | const homeTsxTemplate = nameGenerator("Home.tsx", { |
|
| 44 | + | rpc, |
|
| 45 | + | shadcn, |
|
| 46 | + | tailwind, |
|
| 47 | + | tanstackQuery, |
|
| 48 | + | }); |
|
| 49 | + | ||
| 50 | + | const homeTsxSrc = path.join( |
|
| 51 | + | EXTRAS_DIR, |
|
| 52 | + | "client", |
|
| 53 | + | "src", |
|
| 54 | + | "components", |
|
| 55 | + | "Home.tsx", |
|
| 56 | + | homeTsxTemplate, |
|
| 57 | + | ); |
|
| 58 | + | const homeTsxTarget = path.join( |
|
| 59 | + | projectPath, |
|
| 60 | + | "client", |
|
| 61 | + | "src", |
|
| 62 | + | "components", |
|
| 63 | + | "Home.tsx", |
|
| 64 | + | ); |
|
| 65 | + | fs.copySync(homeTsxSrc, homeTsxTarget); |
|
| 46 | 66 | ||
| 47 | 67 | spinner.success("React Router setup completed"); |
|
| 48 | 68 | return true; |
|
| 3 | 3 | import path from "node:path"; |
|
| 4 | 4 | import { tanstackQueryInstaller } from "@/installers/tanstack-query"; |
|
| 5 | 5 | import { rpcInstaller } from "@/installers/rpc"; |
|
| 6 | + | import { reactRouterInstaller } from "@/installers/react-router"; |
|
| 6 | 7 | ||
| 7 | 8 | export async function installPackages( |
|
| 8 | 9 | options: Required<ProjectOptions>, |
|
| 22 | 23 | if (router !== "none") { |
|
| 23 | 24 | switch (router) { |
|
| 24 | 25 | case "reactrouter": { |
|
| 25 | - | console.log("Instlling React Router"); |
|
| 26 | + | await reactRouterInstaller(options); |
|
| 26 | 27 | break; |
|
| 27 | 28 | } |
|
| 28 | 29 | case "tanstackrouter": { |
|
Binary file — no preview.
Binary file — no preview.
Binary file — no preview.
Binary file — no preview.
Binary file — no preview.
Binary file — no preview.
Binary file — no preview.
Binary file — no preview.
Binary file — no preview.
Binary file — no preview.
Binary file — no preview.
| 1 | + | import { BrowserRouter, Routes, Route } from "react-router"; |
|
| 2 | + | import Home from "./components/Home"; |
|
| 3 | + | ||
| 4 | + | function App() { |
|
| 5 | + | return ( |
|
| 6 | + | <BrowserRouter> |
|
| 7 | + | <Routes> |
|
| 8 | + | <Route path="/" element={<Home />} /> |
|
| 9 | + | </Routes> |
|
| 10 | + | </BrowserRouter> |
|
| 11 | + | ); |
|
| 12 | + | } |
|
| 13 | + | ||
| 14 | + | export default App; |
| 1 | + | import { useState } from "react"; |
|
| 2 | + | import beaver from "@/assets/beaver.svg"; |
|
| 3 | + | import { ApiResponse } from "shared"; |
|
| 4 | + | import { Button } from "@/components/ui/button"; |
|
| 5 | + | ||
| 6 | + | const SERVER_URL = import.meta.env.VITE_SERVER_URL || "http://localhost:3000"; |
|
| 7 | + | ||
| 8 | + | function Home() { |
|
| 9 | + | const [data, setData] = useState<ApiResponse | undefined>(); |
|
| 10 | + | ||
| 11 | + | async function sendRequest() { |
|
| 12 | + | try { |
|
| 13 | + | const req = await fetch(`${SERVER_URL}/hello`); |
|
| 14 | + | const res: ApiResponse = await req.json(); |
|
| 15 | + | setData(res); |
|
| 16 | + | } catch (error) { |
|
| 17 | + | console.log(error); |
|
| 18 | + | } |
|
| 19 | + | } |
|
| 20 | + | ||
| 21 | + | return ( |
|
| 22 | + | <div className="max-w-xl mx-auto flex flex-col gap-6 items-center justify-center min-h-screen"> |
|
| 23 | + | <a href="https://github.com/stevedylandev/bhvr" target="_blank"> |
|
| 24 | + | <img |
|
| 25 | + | src={beaver} |
|
| 26 | + | className="w-16 h-16 cursor-pointer" |
|
| 27 | + | alt="beaver logo" |
|
| 28 | + | /> |
|
| 29 | + | </a> |
|
| 30 | + | <h1 className="text-5xl font-black">bhvr</h1> |
|
| 31 | + | <h2 className="text-2xl font-bold">Bun + Hono + Vite + React</h2> |
|
| 32 | + | <p>A typesafe fullstack monorepo</p> |
|
| 33 | + | <div className="flex items-center gap-4"> |
|
| 34 | + | <Button onClick={sendRequest}>Call API</Button> |
|
| 35 | + | <Button variant="secondary" asChild> |
|
| 36 | + | <a target="_blank" href="https://bhvr.dev"> |
|
| 37 | + | Docs |
|
| 38 | + | </a> |
|
| 39 | + | </Button> |
|
| 40 | + | </div> |
|
| 41 | + | {data && ( |
|
| 42 | + | <pre className="bg-gray-100 p-4 rounded-md"> |
|
| 43 | + | <code> |
|
| 44 | + | Message: {data.message} <br /> |
|
| 45 | + | Success: {data.success.toString()} |
|
| 46 | + | </code> |
|
| 47 | + | </pre> |
|
| 48 | + | )} |
|
| 49 | + | </div> |
|
| 50 | + | ); |
|
| 51 | + | } |
|
| 52 | + | ||
| 53 | + | export default Home; |
| 1 | + | import { useState } from "react"; |
|
| 2 | + | import beaver from "../assets/beaver.svg"; |
|
| 3 | + | import { ApiResponse } from "shared"; |
|
| 4 | + | ||
| 5 | + | const SERVER_URL = import.meta.env.VITE_SERVER_URL || "http://localhost:3000"; |
|
| 6 | + | ||
| 7 | + | function Home() { |
|
| 8 | + | const [data, setData] = useState<ApiResponse | undefined>(); |
|
| 9 | + | ||
| 10 | + | async function sendRequest() { |
|
| 11 | + | try { |
|
| 12 | + | const req = await fetch(`${SERVER_URL}/hello`); |
|
| 13 | + | const res: ApiResponse = await req.json(); |
|
| 14 | + | setData(res); |
|
| 15 | + | } catch (error) { |
|
| 16 | + | console.log(error); |
|
| 17 | + | } |
|
| 18 | + | } |
|
| 19 | + | ||
| 20 | + | return ( |
|
| 21 | + | <div className="max-w-xl mx-auto flex flex-col gap-6 items-center justify-center min-h-screen"> |
|
| 22 | + | <a href="https://github.com/stevedylandev/bhvr" target="_blank"> |
|
| 23 | + | <img |
|
| 24 | + | src={beaver} |
|
| 25 | + | className="w-16 h-16 cursor-pointer" |
|
| 26 | + | alt="beaver logo" |
|
| 27 | + | /> |
|
| 28 | + | </a> |
|
| 29 | + | <h1 className="text-5xl font-black">bhvr</h1> |
|
| 30 | + | <h2 className="text-2xl font-bold">Bun + Hono + Vite + React</h2> |
|
| 31 | + | <p>A typesafe fullstack monorepo</p> |
|
| 32 | + | <div className="flex items-center gap-4"> |
|
| 33 | + | <button |
|
| 34 | + | onClick={sendRequest} |
|
| 35 | + | className="bg-black text-white px-2.5 py-1.5 rounded-md" |
|
| 36 | + | > |
|
| 37 | + | Call API |
|
| 38 | + | </button> |
|
| 39 | + | <a |
|
| 40 | + | target="_blank" |
|
| 41 | + | href="https://bhvr.dev" |
|
| 42 | + | className="border-1 border-black text-black px-2.5 py-1.5 rounded-md" |
|
| 43 | + | > |
|
| 44 | + | Docs |
|
| 45 | + | </a> |
|
| 46 | + | </div> |
|
| 47 | + | {data && ( |
|
| 48 | + | <pre className="bg-gray-100 p-4 rounded-md"> |
|
| 49 | + | <code> |
|
| 50 | + | Message: {data.message} <br /> |
|
| 51 | + | Success: {data.success.toString()} |
|
| 52 | + | </code> |
|
| 53 | + | </pre> |
|
| 54 | + | )} |
|
| 55 | + | </div> |
|
| 56 | + | ); |
|
| 57 | + | } |
|
| 58 | + | ||
| 59 | + | export default Home; |
| 1 | + | import { useState } from "react"; |
|
| 2 | + | import beaver from "../assets/beaver.svg"; |
|
| 3 | + | import type { ApiResponse } from "shared"; |
|
| 4 | + | import "../App.css"; |
|
| 5 | + | ||
| 6 | + | const SERVER_URL = import.meta.env.VITE_SERVER_URL || "http://localhost:3000"; |
|
| 7 | + | ||
| 8 | + | function Home() { |
|
| 9 | + | const [data, setData] = useState<ApiResponse | undefined>(); |
|
| 10 | + | ||
| 11 | + | async function sendRequest() { |
|
| 12 | + | try { |
|
| 13 | + | const req = await fetch(`${SERVER_URL}/hello`); |
|
| 14 | + | const res: ApiResponse = await req.json(); |
|
| 15 | + | setData(res); |
|
| 16 | + | } catch (error) { |
|
| 17 | + | console.log(error); |
|
| 18 | + | } |
|
| 19 | + | } |
|
| 20 | + | ||
| 21 | + | return ( |
|
| 22 | + | <> |
|
| 23 | + | <div> |
|
| 24 | + | <a href="https://github.com/stevedylandev/bhvr" target="_blank"> |
|
| 25 | + | <img src={beaver} className="logo" alt="beaver logo" /> |
|
| 26 | + | </a> |
|
| 27 | + | </div> |
|
| 28 | + | <h1>bhvr</h1> |
|
| 29 | + | <h2>Bun + Hono + Vite + React</h2> |
|
| 30 | + | <p>A typesafe fullstack monorepo</p> |
|
| 31 | + | <div className="card"> |
|
| 32 | + | <div className="button-container"> |
|
| 33 | + | <button onClick={sendRequest}>Call API</button> |
|
| 34 | + | <a className="docs-link" target="_blank" href="https://bhvr.dev"> |
|
| 35 | + | Docs |
|
| 36 | + | </a> |
|
| 37 | + | </div> |
|
| 38 | + | {data && ( |
|
| 39 | + | <pre className="response"> |
|
| 40 | + | <code> |
|
| 41 | + | Message: {data.message} <br /> |
|
| 42 | + | Success: {data.success.toString()} |
|
| 43 | + | </code> |
|
| 44 | + | </pre> |
|
| 45 | + | )} |
|
| 46 | + | </div> |
|
| 47 | + | </> |
|
| 48 | + | ); |
|
| 49 | + | } |
|
| 50 | + | ||
| 51 | + | export default Home; |