diff --git a/webui2/index.html b/webui2/index.html
index 2557eff81159ac1123800343f2eba2245a2631b6..a4e90096c9897376a43961bb58066d249db8f5e4 100644
--- a/webui2/index.html
+++ b/webui2/index.html
@@ -2,8 +2,11 @@
-
+
+
+
+
git-bug
diff --git a/webui2/package.json b/webui2/package.json
index 9578439a4c3d131b00d3a68e7e742fbc7571e40a..cb335e0d1c1c9b15e4dabbd0386aeb6e176cb695 100644
--- a/webui2/package.json
+++ b/webui2/package.json
@@ -58,6 +58,7 @@
"tailwindcss": "^4.2.2",
"typescript": "^6.0.2",
"vite": "^8.0.3",
+ "vite-plugin-svgr": "^5.0.0",
"vite-tsconfig-paths": "^6.1.1"
},
"packageManager": "pnpm@10.33.0+sha512.10568bb4a6afb58c9eb3630da90cc9516417abebd3fabbe6739f0ae795728da1491e9db5a544c76ad8eb7570f5c4bb3d6c637b2cb41bfdcdb47fa823c8649319"
diff --git a/webui2/pnpm-lock.yaml b/webui2/pnpm-lock.yaml
index b1b37af11b6836e1a846734eef338ea82b9d7836..6bf2a839105a0fd366e3043cd5d042db35bab0cd 100644
--- a/webui2/pnpm-lock.yaml
+++ b/webui2/pnpm-lock.yaml
@@ -132,6 +132,9 @@ importers:
vite:
specifier: ^8.0.3
version: 8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3)
+ vite-plugin-svgr:
+ specifier: ^5.0.0
+ version: 5.0.0(typescript@6.0.2)(vite@8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3))
vite-tsconfig-paths:
specifier: ^6.1.1
version: 6.1.1(typescript@6.0.2)(vite@8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3))
@@ -1927,10 +1930,87 @@ packages:
'@rolldown/pluginutils@1.0.0-rc.7':
resolution: {integrity: sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA==}
+ '@rollup/pluginutils@5.3.0':
+ resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
+ peerDependenciesMeta:
+ rollup:
+ optional: true
+
'@sindresorhus/is@4.6.0':
resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==}
engines: {node: '>=10'}
+ '@svgr/babel-plugin-add-jsx-attribute@8.0.0':
+ resolution: {integrity: sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-plugin-remove-jsx-attribute@8.0.0':
+ resolution: {integrity: sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0':
+ resolution: {integrity: sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0':
+ resolution: {integrity: sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-plugin-svg-dynamic-title@8.0.0':
+ resolution: {integrity: sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-plugin-svg-em-dimensions@8.0.0':
+ resolution: {integrity: sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-plugin-transform-react-native-svg@8.1.0':
+ resolution: {integrity: sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-plugin-transform-svg-component@8.0.0':
+ resolution: {integrity: sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==}
+ engines: {node: '>=12'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-preset@8.1.0':
+ resolution: {integrity: sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/core@8.1.0':
+ resolution: {integrity: sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==}
+ engines: {node: '>=14'}
+
+ '@svgr/hast-util-to-babel-ast@8.0.0':
+ resolution: {integrity: sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==}
+ engines: {node: '>=14'}
+
+ '@svgr/plugin-jsx@8.1.0':
+ resolution: {integrity: sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@svgr/core': '*'
+
'@tailwindcss/node@4.2.2':
resolution: {integrity: sha512-pXS+wJ2gZpVXqFaUEjojq7jzMpTGf8rU6ipJz5ovJV6PUGmlJ+jvIwGrzdHdQ80Sg+wmQxUFuoW1UAAwHNEdFA==}
@@ -2276,6 +2356,10 @@ packages:
camel-case@4.1.2:
resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==}
+ camelcase@6.3.0:
+ resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
+ engines: {node: '>=10'}
+
caniuse-lite@1.0.30001781:
resolution: {integrity: sha512-RdwNCyMsNBftLjW6w01z8bKEvT6e/5tpPVEgtn22TiLGlstHOVecsX2KHFkD5e/vRnIE4EGzpuIODb3mtswtkw==}
@@ -2475,6 +2559,10 @@ packages:
resolution: {integrity: sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==}
engines: {node: '>=10.13.0'}
+ entities@4.5.0:
+ resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
+ engines: {node: '>=0.12'}
+
entities@6.0.1:
resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==}
engines: {node: '>=0.12'}
@@ -2511,6 +2599,9 @@ packages:
estree-util-is-identifier-name@3.0.0:
resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==}
+ estree-walker@2.0.2:
+ resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
+
eventemitter3@5.0.4:
resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==}
@@ -3480,6 +3571,9 @@ packages:
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
engines: {node: '>=8'}
+ svg-parser@2.0.4:
+ resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==}
+
swap-case@2.0.2:
resolution: {integrity: sha512-kc6S2YS/2yXbtkSMunBtKdah4VFETZ8Oh6ONSmSd9bRxhqTrtARUCBUiWXH3xVPpvR7tz2CSnkuXVE42EcGnMw==}
@@ -3654,6 +3748,11 @@ packages:
vfile@6.0.3:
resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
+ vite-plugin-svgr@5.0.0:
+ resolution: {integrity: sha512-CZFWDtbWSLnF6C+uv8u7E5Ao6UVQYBpJrS6212XsEod/Lm4ErhOoFc01/po4ie5hqvMCr5KYrlMrSGQQEtMtBg==}
+ peerDependencies:
+ vite: '>=3.0.0'
+
vite-tsconfig-paths@6.1.1:
resolution: {integrity: sha512-2cihq7zliibCCZ8P9cKJrQBkfgdvcFkOOc3Y02o3GWUDLgqjWsZudaoiuOwO/gzTzy17cS5F7ZPo4bsnS4DGkg==}
peerDependencies:
@@ -5549,8 +5648,84 @@ snapshots:
'@rolldown/pluginutils@1.0.0-rc.7': {}
+ '@rollup/pluginutils@5.3.0':
+ dependencies:
+ '@types/estree': 1.0.8
+ estree-walker: 2.0.2
+ picomatch: 4.0.4
+
'@sindresorhus/is@4.6.0': {}
+ '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+
+ '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+
+ '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+
+ '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+
+ '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+
+ '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+
+ '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+
+ '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+
+ '@svgr/babel-preset@8.1.0(@babel/core@7.29.0)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.29.0)
+ '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.29.0)
+ '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.29.0)
+ '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.29.0)
+ '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.29.0)
+ '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.29.0)
+ '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.29.0)
+ '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.29.0)
+
+ '@svgr/core@8.1.0(typescript@6.0.2)':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@svgr/babel-preset': 8.1.0(@babel/core@7.29.0)
+ camelcase: 6.3.0
+ cosmiconfig: 8.3.6(typescript@6.0.2)
+ snake-case: 3.0.4
+ transitivePeerDependencies:
+ - supports-color
+ - typescript
+
+ '@svgr/hast-util-to-babel-ast@8.0.0':
+ dependencies:
+ '@babel/types': 7.29.0
+ entities: 4.5.0
+
+ '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@6.0.2))':
+ dependencies:
+ '@babel/core': 7.29.0
+ '@svgr/babel-preset': 8.1.0(@babel/core@7.29.0)
+ '@svgr/core': 8.1.0(typescript@6.0.2)
+ '@svgr/hast-util-to-babel-ast': 8.0.0
+ svg-parser: 2.0.4
+ transitivePeerDependencies:
+ - supports-color
+
'@tailwindcss/node@4.2.2':
dependencies:
'@jridgewell/remapping': 2.3.5
@@ -5871,6 +6046,8 @@ snapshots:
pascal-case: 3.1.2
tslib: 2.8.1
+ camelcase@6.3.0: {}
+
caniuse-lite@1.0.30001781: {}
capital-case@1.0.4:
@@ -6065,6 +6242,8 @@ snapshots:
graceful-fs: 4.2.11
tapable: 2.3.2
+ entities@4.5.0: {}
+
entities@6.0.1: {}
env-paths@2.2.1: {}
@@ -6112,6 +6291,8 @@ snapshots:
estree-util-is-identifier-name@3.0.0: {}
+ estree-walker@2.0.2: {}
+
eventemitter3@5.0.4: {}
extend@3.0.2: {}
@@ -7440,6 +7621,8 @@ snapshots:
dependencies:
has-flag: 4.0.0
+ svg-parser@2.0.4: {}
+
swap-case@2.0.2:
dependencies:
tslib: 2.8.1
@@ -7606,6 +7789,17 @@ snapshots:
'@types/unist': 3.0.3
vfile-message: 4.0.3
+ vite-plugin-svgr@5.0.0(typescript@6.0.2)(vite@8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3)):
+ dependencies:
+ '@rollup/pluginutils': 5.3.0
+ '@svgr/core': 8.1.0(typescript@6.0.2)
+ '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@6.0.2))
+ vite: 8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3)
+ transitivePeerDependencies:
+ - rollup
+ - supports-color
+ - typescript
+
vite-tsconfig-paths@6.1.1(typescript@6.0.2)(vite@8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.3)):
dependencies:
debug: 4.4.3
diff --git a/webui2/public/favicon.ico b/webui2/public/favicon.ico
new file mode 100644
index 0000000000000000000000000000000000000000..88783392bff8d4ebb486422e2015aa9aaab3ce96
Binary files /dev/null and b/webui2/public/favicon.ico differ
diff --git a/webui2/public/favicon.svg b/webui2/public/favicon.svg
new file mode 100644
index 0000000000000000000000000000000000000000..b3ea7514998672bc9cac5acbbfca036542e4de40
--- /dev/null
+++ b/webui2/public/favicon.svg
@@ -0,0 +1,16 @@
+
diff --git a/webui2/src/assets/logo.svg b/webui2/src/assets/logo.svg
new file mode 100644
index 0000000000000000000000000000000000000000..b3ea7514998672bc9cac5acbbfca036542e4de40
--- /dev/null
+++ b/webui2/src/assets/logo.svg
@@ -0,0 +1,16 @@
+
diff --git a/webui2/src/components/layout/Header.tsx b/webui2/src/components/layout/Header.tsx
index f66883bebef51086ae4871882deb0789419ef420..4bfc0f89a2f37b6039420b4fd59ca14ec60835e7 100644
--- a/webui2/src/components/layout/Header.tsx
+++ b/webui2/src/components/layout/Header.tsx
@@ -7,8 +7,9 @@
// action when logged in.
import { Link, useParams, useRouterState } from "@tanstack/react-router";
-import { Bug, Plus, Sun, Moon, LogIn, LogOut } from "lucide-react";
+import { Plus, Sun, Moon, LogIn, LogOut } from "lucide-react";
+import Logo from "@/assets/logo.svg?react";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { Button } from "@/components/ui/button";
import { ButtonLink } from "@/components/ui/button-link";
@@ -48,7 +49,7 @@ export function Header() {
{/* Logo always goes to the repo picker root */}
-
+
git-bug
diff --git a/webui2/src/vite-env.d.ts b/webui2/src/vite-env.d.ts
index 11f02fe2a0061d6e6e1f271b21da95423b448b32..b1f45c7866694dbf083c82024b97603ad1df0606 100644
--- a/webui2/src/vite-env.d.ts
+++ b/webui2/src/vite-env.d.ts
@@ -1 +1,2 @@
///
+///
diff --git a/webui2/vite.config.ts b/webui2/vite.config.ts
index b76b5074aae409fa399fc384b2b9a43a855e386c..95bcfbe91794bb3b4121fabdd4815c618399a997 100644
--- a/webui2/vite.config.ts
+++ b/webui2/vite.config.ts
@@ -2,6 +2,7 @@ import tailwindcss from "@tailwindcss/vite";
import { tanstackRouter } from "@tanstack/router-plugin/vite";
import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";
+import svgr from "vite-plugin-svgr";
import tsconfigPaths from "vite-tsconfig-paths";
// The Go backend URL. Run: git-bug webui --port 3000
@@ -11,6 +12,7 @@ export default defineConfig({
plugins: [
tanstackRouter({ target: "react", autoCodeSplitting: true }),
tsconfigPaths(),
+ svgr(),
tailwindcss(),
react(),
],