From a227bb45f65e3aaf5efd50bcf5a7c86a880d670d Mon Sep 17 00:00:00 2001 From: klopez4212 Date: Mon, 13 Jul 2026 19:20:34 +0100 Subject: [PATCH] Refresh invite and repository web pages (#1808) Signed-off-by: Fizz <8a675edd33677aa0389f6650d467b2041fb0df4ca820eacb009babb95e3715d4@sprout-oss.stage.blox.sqprod.co> Co-authored-by: npub13fn4ahfnvaa2qwylvegdgeajqs0mph6v4qsw4jcqnw4mjh3hzh2quuucm5 <8a675edd33677aa0389f6650d467b2041fb0df4ca820eacb009babb95e3715d4@sprout-oss.stage.blox.sqprod.co> --- web/src/app/routes/root.tsx | 12 +- web/src/assets/app-icon@3x.png | Bin 0 -> 5101 bytes web/src/features/invite/ui/InvitePage.tsx | 78 ++++---- web/src/features/repos/mock-repos.ts | 149 +++++++++++++++ web/src/features/repos/ui/ConnectButton.tsx | 5 +- web/src/features/repos/ui/OrgSidebar.tsx | 4 +- web/src/features/repos/ui/RepoBlobViewer.tsx | 57 ++++-- .../features/repos/ui/RepoCommitsSection.tsx | 24 +-- web/src/features/repos/ui/RepoDetailPage.tsx | 169 ++++++++++++------ web/src/features/repos/ui/RepoListItem.tsx | 24 ++- .../features/repos/ui/RepoReadmeSection.tsx | 14 +- web/src/features/repos/ui/RepoRefsSection.tsx | 20 ++- web/src/features/repos/ui/RepoTreeSection.tsx | 38 ++-- web/src/features/repos/ui/ReposPage.tsx | 88 +++++---- web/src/features/repos/use-repo-context.ts | 11 +- web/src/features/repos/use-repo-refs.ts | 13 +- web/src/features/repos/use-repos.ts | 11 +- web/src/shared/theme/ThemeProvider.tsx | 29 +-- 18 files changed, 528 insertions(+), 218 deletions(-) create mode 100644 web/src/assets/app-icon@3x.png create mode 100644 web/src/features/repos/mock-repos.ts diff --git a/web/src/app/routes/root.tsx b/web/src/app/routes/root.tsx index 3d6f6efb4..5125eae97 100644 --- a/web/src/app/routes/root.tsx +++ b/web/src/app/routes/root.tsx @@ -1,5 +1,4 @@ -import { Link, Outlet, createRootRoute } from "@tanstack/react-router"; -import { ThemeToggle } from "@/shared/theme/ThemeToggle"; +import { Outlet, createRootRoute } from "@tanstack/react-router"; export const Route = createRootRoute({ component: RootLayout, @@ -8,15 +7,6 @@ export const Route = createRootRoute({ function RootLayout() { return (
-
- - Buzz - - -
diff --git a/web/src/assets/app-icon@3x.png b/web/src/assets/app-icon@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..8b358a48802936f15defaeae158f1796e90f4136 GIT binary patch literal 5101 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 -
- -
-

- You're invited to join -

-

{host}

-

- Buzz is a messaging platform for human–agent collaboration. Accept this - invite in the desktop app to join the workspace on this relay. -

+
+
+
+ Buzz +
+

+ You're invited to join +

+

{host}

- + -

- Already have Buzz installed? “Open in Buzz” will launch it - and accept the invite. Otherwise download the app first, then come back - and use this link again. -

+

+ Don't have the app?{" "} + + Download it now + +

+
); } diff --git a/web/src/features/repos/mock-repos.ts b/web/src/features/repos/mock-repos.ts new file mode 100644 index 000000000..c2e2394d9 --- /dev/null +++ b/web/src/features/repos/mock-repos.ts @@ -0,0 +1,149 @@ +import type { Repo } from "./use-repos"; +import type { + BlobView, + CommitInfo, + ReadmeResult, + TreeEntry, +} from "./git-client"; + +const now = Math.floor(Date.now() / 1000); +const people = { + ada: "1".repeat(64), + grace: "2".repeat(64), + linus: "3".repeat(64), + margaret: "4".repeat(64), +}; + +/** Local-only data for previewing the populated repositories state. */ +export const mockRepos: Repo[] = [ + { + id: "buzz-desktop", + name: "buzz-desktop", + description: + "The desktop client for collaborating with people and agents across Buzz workspaces.", + cloneUrls: ["https://example.com/buzz-desktop.git"], + webUrl: null, + channelId: null, + owner: people.ada, + contributors: [people.grace, people.linus], + createdAt: now - 60 * 24, + }, + { + id: "agent-harness", + name: "agent-harness", + description: + "Tools and shared workflows for launching and coordinating coding agents.", + cloneUrls: ["https://example.com/agent-harness.git"], + webUrl: null, + channelId: null, + owner: people.grace, + contributors: [people.ada, people.margaret], + createdAt: now - 60 * 60 * 3, + }, + { + id: "relay-infrastructure", + name: "relay-infrastructure", + description: + "Infrastructure and deployment configuration for community relays.", + cloneUrls: ["https://example.com/relay-infrastructure.git"], + webUrl: null, + channelId: null, + owner: people.linus, + contributors: [people.margaret], + createdAt: now - 60 * 60 * 24 * 2, + }, + { + id: "design-system", + name: "design-system", + description: "Shared foundations, components, and interaction patterns.", + cloneUrls: ["https://example.com/design-system.git"], + webUrl: null, + channelId: null, + owner: people.margaret, + contributors: [people.ada, people.grace, people.linus], + createdAt: now - 60 * 60 * 24 * 8, + }, +]; + +export function getMockRepo(repoId: string): Repo | undefined { + if (!import.meta.env.DEV) return undefined; + return mockRepos.find((repo) => repo.id === repoId); +} + +export const mockRepoTree: TreeEntry[] = [ + { + name: "src", + type: "tree", + mode: "040000", + oid: "1".repeat(40), + }, + { + name: "README.md", + type: "blob", + mode: "100644", + oid: "2".repeat(40), + }, + { + name: "package.json", + type: "blob", + mode: "100644", + oid: "3".repeat(40), + }, +]; + +export const mockRepoCommits: CommitInfo[] = [ + { + oid: "a".repeat(40), + message: "Polish repository browsing styles", + author: { + name: "Ada", + email: "ada@example.com", + timestamp: now - 60 * 24, + }, + }, + { + oid: "b".repeat(40), + message: "Add repository empty states", + author: { + name: "Grace", + email: "grace@example.com", + timestamp: now - 60 * 60 * 5, + }, + }, +]; + +export const mockRepoReadme: ReadmeResult = { + filename: "README.md", + content: + "# Buzz Desktop\n\nA focused workspace for people and agents to collaborate.\n\n## Getting started\n\nInstall dependencies, then start the development app.", +}; + +export function getMockBlob( + repoId: string, + filepath: string, +): BlobView | undefined { + if (!getMockRepo(repoId)) return undefined; + + if (filepath === "README.md") { + return { + kind: "markdown", + content: mockRepoReadme.content, + sizeBytes: mockRepoReadme.content.length, + }; + } + + if (filepath === "package.json") { + const content = `${JSON.stringify( + { + name: repoId, + private: true, + scripts: { dev: "vite", build: "tsc && vite build" }, + }, + null, + 2, + )}\n`; + return { kind: "text", content, sizeBytes: content.length }; + } + + return undefined; +} diff --git a/web/src/features/repos/ui/ConnectButton.tsx b/web/src/features/repos/ui/ConnectButton.tsx index 68abfbb6e..312955b9c 100644 --- a/web/src/features/repos/ui/ConnectButton.tsx +++ b/web/src/features/repos/ui/ConnectButton.tsx @@ -7,7 +7,10 @@ export function ConnectButton({ className }: { className?: string }) { const deepLink = `buzz://connect?relay=${encodeURIComponent(relayWsUrl())}`; return ( -
{/* Sidebar */} -