feat(frontend): refresh dashboard, orchestrator, and AO logos (#317)
* feat(frontend): refresh dashboard, orchestrator, and AO logos Replaces the dashboard and orchestrator glyphs and the AO brand logo per issue #315. - Dashboard buttons (sidebar action + Open Kanban) now use the asymmetric LayoutDashboard icon instead of the equal-cell LayoutGrid. - Orchestrator buttons (sidebar action + every topbar badge/button) use a new org-chart OrchestratorIcon (parent fanning to three children), authored in lucide's stroke style since lucide has no matching glyph. - The AO brand logo (sidebar header mark, landing nav, docs header) is now the pixel-mascot image; the old ao-logo.svg monogram is removed. Closes #315 * chore: format with prettier [skip ci] * fix(landing): use next/image and next/link for the AO logo and docs link Addresses react-doctor review on #317: the Next.js landing app should use next/image for the brand logo (optimized formats, responsive srcset, lazy loading) and next/link for the internal /docs navigation (client-side routing + prefetch) instead of plain <img>/<a>. --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
parent
93123edd34
commit
b37b6acefe
|
|
@ -1,4 +1,5 @@
|
|||
import type { ReactNode } from "react";
|
||||
import Image from "next/image";
|
||||
import { DocsLayout } from "fumadocs-ui/layouts/docs";
|
||||
import { RootProvider } from "fumadocs-ui/provider";
|
||||
import type { LinkItemType } from "fumadocs-ui/layouts/shared";
|
||||
|
|
@ -82,7 +83,14 @@ export default function Layout({ children }: { children: ReactNode }) {
|
|||
nav={{
|
||||
title: (
|
||||
<span className="flex items-center gap-2 font-semibold">
|
||||
<img src="/ao-logo.svg" alt="" aria-hidden="true" width={22} height={22} className="h-[22px] w-[22px]" />
|
||||
<Image
|
||||
src="/ao-logo.png"
|
||||
alt=""
|
||||
aria-hidden
|
||||
width={22}
|
||||
height={22}
|
||||
className="h-[22px] w-[22px] rounded-[5px] object-cover"
|
||||
/>
|
||||
<span className="text-[var(--color-text-primary)]">AO</span>
|
||||
</span>
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
"use client";
|
||||
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
|
||||
function XIcon() {
|
||||
return (
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
||||
|
|
@ -31,17 +34,24 @@ export function LandingNav() {
|
|||
href="#"
|
||||
className="inline-flex items-center gap-2 text-base font-semibold text-white no-underline font-sans font-[680] tracking-tight"
|
||||
>
|
||||
<img src="/ao-logo.svg" alt="" aria-hidden="true" width={28} height={28} className="h-7 w-7" />
|
||||
<Image
|
||||
src="/ao-logo.png"
|
||||
alt=""
|
||||
aria-hidden
|
||||
width={28}
|
||||
height={28}
|
||||
className="h-7 w-7 rounded-md object-cover"
|
||||
/>
|
||||
Agent Orchestrator
|
||||
</a>
|
||||
<ul className="hidden md:flex items-center gap-8 list-none">
|
||||
<li>
|
||||
<a
|
||||
<Link
|
||||
href="/docs"
|
||||
className="text-sm text-[var(--landing-muted)] no-underline hover:text-white transition-colors"
|
||||
>
|
||||
Docs
|
||||
</a>
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 55 KiB |
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 56 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 55 KiB |
|
|
@ -1,6 +1,6 @@
|
|||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import { useNavigate, useParams } from "@tanstack/react-router";
|
||||
import { GitBranch, LayoutGrid, PanelRightClose, PanelRightOpen, Square, Waypoints } from "lucide-react";
|
||||
import { GitBranch, LayoutDashboard, PanelRightClose, PanelRightOpen, Square } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import {
|
||||
findProjectOrchestrator,
|
||||
|
|
@ -14,6 +14,7 @@ import { useWorkspaceQuery, workspaceQueryKey } from "../hooks/useWorkspaceQuery
|
|||
import { apiClient, apiErrorMessage } from "../lib/api-client";
|
||||
import { spawnOrchestrator } from "../lib/spawn-orchestrator";
|
||||
import { useUiStore } from "../stores/ui-store";
|
||||
import { OrchestratorIcon } from "./icons";
|
||||
import { cn } from "../lib/utils";
|
||||
|
||||
const isMac = typeof navigator !== "undefined" && /Mac|iPod|iPhone|iPad/.test(navigator.userAgent);
|
||||
|
|
@ -105,7 +106,7 @@ export function ShellTopbar() {
|
|||
·
|
||||
</span>
|
||||
<span className="session-detail-mode-badge session-detail-mode-badge--neutral">
|
||||
<Waypoints className="size-3 shrink-0" aria-hidden="true" />
|
||||
<OrchestratorIcon className="size-3 shrink-0" aria-hidden="true" />
|
||||
Orchestrator
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -138,7 +139,7 @@ export function ShellTopbar() {
|
|||
style={noDragStyle}
|
||||
type="button"
|
||||
>
|
||||
<LayoutGrid className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
<LayoutDashboard className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
Open Kanban
|
||||
</button>
|
||||
) : (
|
||||
|
|
@ -150,7 +151,7 @@ export function ShellTopbar() {
|
|||
style={noDragStyle}
|
||||
type="button"
|
||||
>
|
||||
<Waypoints className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
<OrchestratorIcon className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
{isSpawning ? "Spawning…" : "Open orchestrator"}
|
||||
</button>
|
||||
)}
|
||||
|
|
@ -190,7 +191,7 @@ export function ShellTopbar() {
|
|||
style={noDragStyle}
|
||||
type="button"
|
||||
>
|
||||
<Waypoints className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
<OrchestratorIcon className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
Orchestrator
|
||||
</button>
|
||||
) : (
|
||||
|
|
@ -202,7 +203,7 @@ export function ShellTopbar() {
|
|||
style={noDragStyle}
|
||||
type="button"
|
||||
>
|
||||
<Waypoints className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
<OrchestratorIcon className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
{isSpawning ? "Spawning…" : "Spawn Orchestrator"}
|
||||
</button>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { useNavigate, useParams, useRouterState } from "@tanstack/react-router";
|
|||
import {
|
||||
ChevronRight,
|
||||
GitPullRequest,
|
||||
LayoutGrid,
|
||||
LayoutDashboard,
|
||||
Moon,
|
||||
MoreVertical,
|
||||
Plus,
|
||||
|
|
@ -11,7 +11,6 @@ import {
|
|||
Settings,
|
||||
Sun,
|
||||
Trash2,
|
||||
Waypoints,
|
||||
} from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import {
|
||||
|
|
@ -53,6 +52,8 @@ import {
|
|||
useSidebar,
|
||||
} from "./ui/sidebar";
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from "./ui/tooltip";
|
||||
import { OrchestratorIcon } from "./icons";
|
||||
import aoLogo from "../assets/ao-logo.png";
|
||||
import { cn } from "../lib/utils";
|
||||
import { useUiStore } from "../stores/ui-store";
|
||||
|
||||
|
|
@ -158,8 +159,8 @@ export function Sidebar({ daemonStatus, workspaceError, workspaces, onCreateProj
|
|||
<button
|
||||
aria-label="Orchestrator board"
|
||||
className={cn(
|
||||
"grid h-[22px] w-[22px] shrink-0 place-items-center rounded-[6px] bg-accent text-accent-foreground",
|
||||
"group-data-[collapsible=icon]:size-9 group-data-[collapsible=icon]:rounded-lg group-data-[collapsible=icon]:bg-transparent group-data-[collapsible=icon]:text-current",
|
||||
"grid h-[22px] w-[22px] shrink-0 place-items-center",
|
||||
"group-data-[collapsible=icon]:size-9 group-data-[collapsible=icon]:rounded-lg",
|
||||
selection.isHome
|
||||
? "group-data-[collapsible=icon]:bg-interactive-active"
|
||||
: "group-data-[collapsible=icon]:hover:bg-interactive-hover",
|
||||
|
|
@ -167,9 +168,7 @@ export function Sidebar({ daemonStatus, workspaceError, workspaces, onCreateProj
|
|||
onClick={selection.goHome}
|
||||
type="button"
|
||||
>
|
||||
<span className="contents group-data-[collapsible=icon]:grid group-data-[collapsible=icon]:h-[22px] group-data-[collapsible=icon]:w-[22px] group-data-[collapsible=icon]:place-items-center group-data-[collapsible=icon]:rounded-[6px] group-data-[collapsible=icon]:bg-accent group-data-[collapsible=icon]:text-accent-foreground">
|
||||
<Waypoints className="h-3.5 w-3.5" aria-hidden="true" />
|
||||
</span>
|
||||
<img src={aoLogo} alt="" aria-hidden="true" className="h-[22px] w-[22px] rounded-[6px] object-cover" />
|
||||
</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="right" hidden={state !== "collapsed"}>
|
||||
|
|
@ -493,7 +492,7 @@ function ProjectItem({
|
|||
onClick={() => selection.goProject(workspace.id)}
|
||||
type="button"
|
||||
>
|
||||
<LayoutGrid aria-hidden="true" />
|
||||
<LayoutDashboard aria-hidden="true" />
|
||||
</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Dashboard</TooltipContent>
|
||||
|
|
@ -507,7 +506,7 @@ function ProjectItem({
|
|||
onClick={() => void openOrchestrator()}
|
||||
type="button"
|
||||
>
|
||||
<Waypoints aria-hidden="true" />
|
||||
<OrchestratorIcon aria-hidden="true" />
|
||||
</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
import type { SVGProps } from "react";
|
||||
|
||||
// Orchestrator mark: a parent node fanning out to three child nodes, drawn in
|
||||
// lucide's 24x24 stroke style so it drops into the same slots as the lucide
|
||||
// icons (size comes from `className`/the parent's `[&_svg]:size-*`). Lucide has
|
||||
// no 1-parent / 3-child hierarchy glyph, so we author this one to match the
|
||||
// org-chart icon called for in the design.
|
||||
export function OrchestratorIcon({ className, ...props }: SVGProps<SVGSVGElement>) {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
className={className}
|
||||
{...props}
|
||||
>
|
||||
<circle cx="12" cy="4" r="2" />
|
||||
<circle cx="5" cy="20" r="2" />
|
||||
<circle cx="12" cy="20" r="2" />
|
||||
<circle cx="19" cy="20" r="2" />
|
||||
<path d="M12 6v12" />
|
||||
<path d="M5 11h14" />
|
||||
<path d="M5 11v7" />
|
||||
<path d="M19 11v7" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
Loading…
Reference in New Issue