diff --git a/.github/pr-assets/1517/ccs-bar-panel.webp b/.github/pr-assets/1517/ccs-bar-panel.webp new file mode 100644 index 00000000..bf3b995f Binary files /dev/null and b/.github/pr-assets/1517/ccs-bar-panel.webp differ diff --git a/.github/pr-assets/1517/dashboard-header-ccs-bar-button.png b/.github/pr-assets/1517/dashboard-header-ccs-bar-button.png new file mode 100644 index 00000000..00336bb1 Binary files /dev/null and b/.github/pr-assets/1517/dashboard-header-ccs-bar-button.png differ diff --git a/.github/pr-assets/1517/index.html b/.github/pr-assets/1517/index.html new file mode 100644 index 00000000..0a921ecf --- /dev/null +++ b/.github/pr-assets/1517/index.html @@ -0,0 +1,224 @@ + + + + + + CCS Bar Promo Evidence + + + +
+
+
+

PR 1517 · CCS Bar README and dashboard promotion

+

+ Captures from local branch kai/feat/ccs-bar-promo. Dashboard capture uses + Vite at 127.0.0.1:5187, light theme, 1440x900 viewport, local auth-check + stubbed open, and no private account data. +

+
+ +
+ +
+
+

What Changed

+

README now introduces CCS Bar, and dashboard chrome shows a compact global CCS Bar link.

+
+
+

Why It Matters

+

Users can discover the native macOS quota and usage companion from every dashboard route.

+
+
+

Review Cue

+

Red callout marks the new top-bar button next to ClaudeKit and Sponsor controls.

+
+
+ +
+

1. Global Dashboard Entry Point

+

The compact CCS Bar button is visible in the persistent dashboard header.

+
+
+
+ IMPLEMENTED + Dashboard chrome +
+ CCS dashboard header with red callout around the CCS Bar button +
+
+
+ CURRENT SNAPSHOT + Sanitized CCS Bar panel +
+ Sanitized CCS Bar macOS panel showing quota, spend, and account controls +
+
+
+
+ + + diff --git a/README.md b/README.md index ab892b40..1d1c24cb 100644 --- a/README.md +++ b/README.md @@ -116,6 +116,17 @@ Need the full setup path instead of the short version? ## See CCS In Action +### CCS Bar For macOS + +![CCS Bar](assets/screenshots/ccs-bar-panel.webp) + +CCS Bar puts live subscription quota, daily spend, and account controls in the +macOS menu bar. Install it with `ccs bar install`, launch it with `ccs bar`, and +tell us what would make it more useful: issues and ideas are welcome in +[GitHub Issues](https://github.com/kaitranntt/ccs/issues). + +Deep dive: [CCS Bar](https://docs.ccs.kaitran.ca/features/dashboard/ccs-bar). + ### Usage Analytics ![Analytics Dashboard](assets/screenshots/analytics.webp) @@ -164,6 +175,7 @@ reference material. | Install CCS cleanly on a new machine | [Installation](https://docs.ccs.kaitran.ca/getting-started/installation) | | Go from install to a successful first run | [Your First CCS Session](https://docs.ccs.kaitran.ca/getting-started/first-session) | | See the dashboard and workflow surfaces before setup | [Product Tour](https://docs.ccs.kaitran.ca/getting-started/product-tour) | +| Install the native macOS menu-bar companion | [CCS Bar](https://docs.ccs.kaitran.ca/features/dashboard/ccs-bar) | | Compare OAuth providers, Claude accounts, and API profiles | [Provider Overview](https://docs.ccs.kaitran.ca/providers/concepts/overview) | | Learn the dashboard structure and feature pages | [Dashboard Overview](https://docs.ccs.kaitran.ca/features/dashboard/overview) | | Configure profiles, paths, and environment variables | [Configuration](https://docs.ccs.kaitran.ca/getting-started/configuration) | diff --git a/assets/screenshots/ccs-bar-panel.webp b/assets/screenshots/ccs-bar-panel.webp new file mode 100644 index 00000000..bf3b995f Binary files /dev/null and b/assets/screenshots/ccs-bar-panel.webp differ diff --git a/ui/src/components/layout/layout.tsx b/ui/src/components/layout/layout.tsx index 9216a2c4..aab10e46 100644 --- a/ui/src/components/layout/layout.tsx +++ b/ui/src/components/layout/layout.tsx @@ -10,6 +10,7 @@ import { ConnectionIndicator } from '@/components/shared/connection-indicator'; import { LocalhostDisclaimer } from '@/components/shared/localhost-disclaimer'; import { Skeleton } from '@/components/ui/skeleton'; import { ClaudeKitBadge } from '@/components/shared/claudekit-badge'; +import { CcsBarButton } from '@/components/shared/ccs-bar-button'; import { SponsorButton } from '@/components/shared/sponsor-button'; import { ProjectSelectionDialog } from '@/components/shared/project-selection-dialog'; import { DeviceCodeDialog } from '@/components/shared/device-code-dialog'; @@ -44,6 +45,7 @@ export function Layout() {
+
diff --git a/ui/src/components/profiles/ccs-bar-banner.tsx b/ui/src/components/profiles/ccs-bar-banner.tsx deleted file mode 100644 index d8fb9f3f..00000000 --- a/ui/src/components/profiles/ccs-bar-banner.tsx +++ /dev/null @@ -1,101 +0,0 @@ -/** - * CCS Bar Feature Banner - * Dismissible announcement banner promoting the native macOS menu-bar app. - * - * Rendered only on macOS: the CTA is an install action (`ccs bar install`) that - * has no effect on other platforms, so showing it elsewhere would be misleading. - */ - -/* eslint-disable react-hooks/set-state-in-effect */ -import { useState, useEffect } from 'react'; -import { useTranslation } from 'react-i18next'; -import { X, MonitorDot, ExternalLink } from 'lucide-react'; -import { Button } from '@/components/ui/button'; - -const BANNER_DISMISSED_KEY = 'ccs:ccs-bar-banner-dismissed'; - -// User-facing docs page for CCS Bar (flat Markdown in the ccs/cli docs tree). -const CCS_BAR_DOCS_URL = 'https://github.com/kaitranntt/ccs/blob/main/docs/ccs-bar.md'; - -// Lightweight, dependency-free macOS detection. Kept inline because no other -// component needs platform detection; a shared hook would be premature. -const isMacOS = - typeof navigator !== 'undefined' && - /Mac|iPhone|iPad/i.test(navigator.userAgent || navigator.platform || ''); - -interface CcsBarBannerProps { - onInstallClick?: () => void; -} - -export function CcsBarBanner({ onInstallClick }: CcsBarBannerProps) { - const { t } = useTranslation(); - const [dismissed, setDismissed] = useState(true); // Start hidden to avoid flash - - // Check localStorage on mount - useEffect(() => { - const isDismissed = localStorage.getItem(BANNER_DISMISSED_KEY) === 'true'; - setDismissed(isDismissed); - }, []); - - const handleDismiss = () => { - localStorage.setItem(BANNER_DISMISSED_KEY, 'true'); - setDismissed(true); - }; - - if (!isMacOS) return null; - if (dismissed) return null; - - return ( -
-
-
-
- -
-
-

- {t('ccsBarBanner.new')}: {t('ccsBarBanner.title')} -

-

- {t('ccsBarBanner.description')}{' '} - - ccs bar install - -

-
-
- -
- {onInstallClick && ( - - )} - - Learn more - - - -
-
-
- ); -} diff --git a/ui/src/components/profiles/ccs-bar-promo-card.tsx b/ui/src/components/profiles/ccs-bar-promo-card.tsx deleted file mode 100644 index 70869390..00000000 --- a/ui/src/components/profiles/ccs-bar-promo-card.tsx +++ /dev/null @@ -1,53 +0,0 @@ -/** - * CCS Bar Promo Card - * Permanent promotional card for the native macOS menu-bar app, shown in the - * providers sidebar footer. - * - * Rendered only on macOS: the install CTA has no effect elsewhere. - */ - -import { useTranslation } from 'react-i18next'; -import { Button } from '@/components/ui/button'; -import { MonitorDot } from 'lucide-react'; - -// Lightweight, dependency-free macOS detection (see ccs-bar-banner.tsx). -const isMacOS = - typeof navigator !== 'undefined' && - /Mac|iPhone|iPad/i.test(navigator.userAgent || navigator.platform || ''); - -interface CcsBarPromoCardProps { - onInstallClick: () => void; -} - -export function CcsBarPromoCard({ onInstallClick }: CcsBarPromoCardProps) { - const { t } = useTranslation(); - - if (!isMacOS) return null; - - return ( -
-
-
- -
-
-

- {t('ccsBarPromo.title')} -

-

- {t('ccsBarPromo.description')} -

-
- -
-
- ); -} diff --git a/ui/src/components/profiles/index.ts b/ui/src/components/profiles/index.ts index 6a05ba14..9e28fd2b 100644 --- a/ui/src/components/profiles/index.ts +++ b/ui/src/components/profiles/index.ts @@ -21,9 +21,5 @@ export { OpenRouterPromoCard } from './openrouter-promo-card'; export { OpenRouterQuickStart } from './openrouter-quick-start'; export { AlibabaCodingPlanPromoCard } from './alibaba-coding-plan-promo-card'; -// CCS Bar (native macOS menu-bar app) promo components -export { CcsBarBanner } from './ccs-bar-banner'; -export { CcsBarPromoCard } from './ccs-bar-promo-card'; - export { ModelTierMapping } from './model-tier-mapping'; export type { TierMapping } from './model-tier-mapping'; diff --git a/ui/src/components/shared/ccs-bar-button.tsx b/ui/src/components/shared/ccs-bar-button.tsx new file mode 100644 index 00000000..891f2298 --- /dev/null +++ b/ui/src/components/shared/ccs-bar-button.tsx @@ -0,0 +1,42 @@ +/** + * CCS Bar Button + * + * Compact navbar link for the native macOS menu-bar app docs. + */ + +import { MonitorDot } from 'lucide-react'; +import { useTranslation } from 'react-i18next'; +import { Button } from '@/components/ui/button'; +import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'; + +const CCS_BAR_DOCS_URL = 'https://docs.ccs.kaitran.ca/features/dashboard/ccs-bar'; + +export function CcsBarButton() { + const { t } = useTranslation(); + + return ( + + + + + + {t('ccsBarButton.tooltip')} + + + ); +} diff --git a/ui/src/components/shared/index.ts b/ui/src/components/shared/index.ts index ae67a7e4..06efe755 100644 --- a/ui/src/components/shared/index.ts +++ b/ui/src/components/shared/index.ts @@ -3,6 +3,7 @@ */ export { CcsLogo } from './ccs-logo'; +export { CcsBarButton } from './ccs-bar-button'; export { ClaudeKitBadge } from './claudekit-badge'; export { CodeEditor } from './code-editor'; export { CommandBuilder } from './command-builder'; diff --git a/ui/src/lib/i18n.ts b/ui/src/lib/i18n.ts index 97d46f83..50f097ef 100644 --- a/ui/src/lib/i18n.ts +++ b/ui/src/lib/i18n.ts @@ -1636,6 +1636,11 @@ const resources = { githubLink: { title: 'Report an issue on GitHub', }, + ccsBarButton: { + title: 'Open CCS Bar docs', + label: 'CCS Bar', + tooltip: 'Native macOS menu-bar quota, cost, and account controls', + }, globalEnvIndicator: { injectedCount_one: '{{count}} global env var will be injected at runtime', injectedCount_other: '{{count}} global env vars will be injected at runtime', @@ -2489,17 +2494,6 @@ const resources = { title: 'OpenRouter', description: 'Access hundreds of models from one API endpoint.', }, - ccsBarBanner: { - new: 'NEW', - title: 'CCS Bar for macOS', - description: 'See live subscription quota and usage from your menu bar. Install with', - install: 'Install', - }, - ccsBarPromo: { - title: 'CCS Bar (macOS)', - description: 'Live quota and usage in your menu bar.', - install: 'Install', - }, profileCard: { profile: 'Profile', openRouter: 'OpenRouter profile', @@ -4286,6 +4280,11 @@ const resources = { githubLink: { title: '在 GitHub 上报告问题', }, + ccsBarButton: { + title: '打开 CCS Bar 文档', + label: 'CCS Bar', + tooltip: '原生 macOS 菜单栏配额、成本和账号控制', + }, globalEnvIndicator: { injectedCount_one: '{{count}} 个全局环境变量将在运行时注入', injectedCount_other: '{{count}} 个全局环境变量将在运行时注入', @@ -6984,6 +6983,11 @@ const resources = { githubLink: { title: 'Báo cáo vấn đề trên GitHub', }, + ccsBarButton: { + title: 'Mở tài liệu CCS Bar', + label: 'CCS Bar', + tooltip: 'Điều khiển hạn mức, chi phí và tài khoản trên thanh menu macOS', + }, globalEnvIndicator: { injectedCount_one: '{{count}} biến env toàn cục sẽ được áp dụng khi chạy', injectedCount_other: '{{count}} biến env toàn cục sẽ được áp dụng khi chạy', @@ -10665,6 +10669,11 @@ const resources = { title: 'GitHub でこのプロジェクトをスポンサー', sponsor: 'スポンサー', }, + ccsBarButton: { + title: 'CCS Bar ドキュメントを開く', + label: 'CCS Bar', + tooltip: 'macOS メニューバーでクォータ、コスト、アカウントを確認', + }, supportEntryCard: { actionRequired: '対応が必要', }, @@ -12431,6 +12440,11 @@ const resources = { githubLink: { title: 'GitHub에서 이슈 보고', }, + ccsBarButton: { + title: 'CCS Bar 문서 열기', + label: 'CCS Bar', + tooltip: 'macOS 메뉴 막대에서 할당량, 비용, 계정 제어 확인', + }, globalEnvIndicator: { injectedCount_one: '런타임에 글로벌 환경 변수 {{count}}개가 주입됩니다', injectedCount_other: '런타임에 글로벌 환경 변수 {{count}}개가 주입됩니다', diff --git a/ui/src/pages/api.tsx b/ui/src/pages/api.tsx index 0f44ff7c..532126ad 100644 --- a/ui/src/pages/api.tsx +++ b/ui/src/pages/api.tsx @@ -22,8 +22,6 @@ import { OpenRouterBanner } from '@/components/profiles/openrouter-banner'; import { OpenRouterQuickStart } from '@/components/profiles/openrouter-quick-start'; import { OpenRouterPromoCard } from '@/components/profiles/openrouter-promo-card'; import { AlibabaCodingPlanPromoCard } from '@/components/profiles/alibaba-coding-plan-promo-card'; -import { CcsBarBanner } from '@/components/profiles/ccs-bar-banner'; -import { CcsBarPromoCard } from '@/components/profiles/ccs-bar-promo-card'; import { useProfiles, useDeleteProfile, @@ -43,15 +41,6 @@ import { useTranslation } from 'react-i18next'; import { toast } from 'sonner'; import { useNavigate } from 'react-router-dom'; -// CCS Bar is installed via the `ccs bar install` CLI command, not from the -// dashboard. The promo CTA therefore opens the user-facing docs page where the -// install/launch steps live, rather than triggering an in-app action. -const CCS_BAR_DOCS_URL = 'https://github.com/kaitranntt/ccs/blob/main/docs/ccs-bar.md'; - -function openCcsBarDocs() { - window.open(CCS_BAR_DOCS_URL, '_blank', 'noopener,noreferrer'); -} - export function ApiPage() { const { t } = useTranslation(); const navigate = useNavigate(); @@ -224,7 +213,6 @@ export function ApiPage() { return (
setCreateDialogOpen(true)} /> - openCcsBarDocs()} />
@@ -375,7 +363,6 @@ export function ApiPage() { setCreateDialogOpen(true); }} /> - openCcsBarDocs()} />