1+ import { useAuthStore } from "@features/auth/stores/authStore" ;
12import {
23 type SettingsCategory ,
34 useSettingsDialogStore ,
45} from "@features/settings/stores/settingsDialogStore" ;
6+ import { useSeat } from "@hooks/useSeat" ;
57import {
68 ArrowLeft ,
79 ArrowsClockwise ,
810 CaretRight ,
911 Cloud ,
1012 Code ,
13+ CreditCard ,
1114 Folder ,
1215 GearSix ,
1316 HardDrives ,
1417 Keyboard ,
1518 Palette ,
1619 Plugs ,
20+ SignOut ,
1721 TrafficSignal ,
1822 TreeStructure ,
19- User ,
2023 Wrench ,
2124} from "@phosphor-icons/react" ;
22- import { Box , Flex , ScrollArea , Text } from "@radix-ui/themes" ;
25+ import { Avatar , Box , Flex , ScrollArea , Text } from "@radix-ui/themes" ;
26+ import { useQuery } from "@tanstack/react-query" ;
2327import { type ReactNode , useEffect } from "react" ;
2428import { useHotkeys } from "react-hotkeys-hook" ;
25- import { AccountSettings } from "./sections/AccountSettings" ;
2629import { AdvancedSettings } from "./sections/AdvancedSettings" ;
2730import { ClaudeCodeSettings } from "./sections/ClaudeCodeSettings" ;
2831import { CloudEnvironmentsSettings } from "./sections/CloudEnvironmentsSettings" ;
2932import { EnvironmentsSettings } from "./sections/environments/EnvironmentsSettings" ;
3033import { GeneralSettings } from "./sections/GeneralSettings" ;
3134import { McpServersSettings } from "./sections/McpServersSettings" ;
3235import { PersonalizationSettings } from "./sections/PersonalizationSettings" ;
36+ import { PlanUsageSettings } from "./sections/PlanUsageSettings" ;
3337import { ShortcutsSettings } from "./sections/ShortcutsSettings" ;
3438import { SignalSourcesSettings } from "./sections/SignalSourcesSettings" ;
3539import { UpdatesSettings } from "./sections/UpdatesSettings" ;
@@ -45,7 +49,7 @@ interface SidebarItem {
4549
4650const SIDEBAR_ITEMS : SidebarItem [ ] = [
4751 { id : "general" , label : "General" , icon : < GearSix size = { 16 } /> } ,
48- { id : "account " , label : "Account " , icon : < User size = { 16 } /> } ,
52+ { id : "plan-usage " , label : "Plan & Usage " , icon : < CreditCard size = { 16 } /> } ,
4953 { id : "workspaces" , label : "Workspaces" , icon : < Folder size = { 16 } /> } ,
5054 { id : "worktrees" , label : "Worktrees" , icon : < TreeStructure size = { 16 } /> } ,
5155 {
@@ -78,7 +82,7 @@ const SIDEBAR_ITEMS: SidebarItem[] = [
7882
7983const CATEGORY_TITLES : Record < SettingsCategory , string > = {
8084 general : "General" ,
81- account : "Account " ,
85+ "plan-usage" : "Plan & Usage " ,
8286 workspaces : "Workspaces" ,
8387 worktrees : "Worktrees" ,
8488 environments : "Environments" ,
@@ -95,7 +99,7 @@ const CATEGORY_TITLES: Record<SettingsCategory, string> = {
9599
96100const CATEGORY_COMPONENTS : Record < SettingsCategory , React . ComponentType > = {
97101 general : GeneralSettings ,
98- account : AccountSettings ,
102+ "plan-usage" : PlanUsageSettings ,
99103 workspaces : WorkspacesSettings ,
100104 worktrees : WorktreesSettings ,
101105 environments : EnvironmentsSettings ,
@@ -113,6 +117,17 @@ const CATEGORY_COMPONENTS: Record<SettingsCategory, React.ComponentType> = {
113117export function SettingsDialog ( ) {
114118 const { isOpen, activeCategory, close, setCategory } =
115119 useSettingsDialogStore ( ) ;
120+ const { client, isAuthenticated } = useAuthStore ( ) ;
121+ const { seat, planLabel } = useSeat ( ) ;
122+
123+ const { data : user } = useQuery ( {
124+ queryKey : [ "currentUser" ] ,
125+ queryFn : async ( ) => {
126+ if ( ! client ) return null ;
127+ return await client . getCurrentUser ( ) ;
128+ } ,
129+ enabled : ! ! client && isAuthenticated ,
130+ } ) ;
116131
117132 useHotkeys ( "escape" , close , {
118133 enabled : isOpen ,
@@ -138,13 +153,50 @@ export function SettingsDialog() {
138153
139154 const ActiveComponent = CATEGORY_COMPONENTS [ activeCategory ] ;
140155
156+ const initials = user
157+ ? user . first_name && user . last_name
158+ ? `${ user . first_name [ 0 ] } ${ user . last_name [ 0 ] } ` . toUpperCase ( )
159+ : ( user . email ?. substring ( 0 , 2 ) . toUpperCase ( ) ?? "U" )
160+ : null ;
161+
141162 return (
142163 < div
143164 className = "fixed inset-0 z-[100] flex"
144165 style = { { backgroundColor : "var(--color-background)" } }
145166 data-overlay = "settings"
146167 >
147- < div className = "flex h-full w-[256px] shrink-0 flex-col border-gray-6 border-r pt-8" >
168+ < div className = "flex h-full w-[256px] shrink-0 flex-col border-gray-6 border-r" >
169+ < div
170+ className = "drag"
171+ style = { {
172+ height : 36 ,
173+ flexShrink : 0 ,
174+ borderBottom : "1px solid var(--gray-6)" ,
175+ } }
176+ />
177+
178+ { isAuthenticated && user && initials && (
179+ < Flex
180+ align = "center"
181+ gap = "3"
182+ px = "3"
183+ py = "3"
184+ style = { { borderBottom : "1px solid var(--gray-5)" } }
185+ >
186+ < Avatar size = "2" fallback = { initials } radius = "full" color = "amber" />
187+ < Flex direction = "column" style = { { minWidth : 0 } } >
188+ < Text size = "2" weight = "medium" truncate >
189+ { user . email }
190+ </ Text >
191+ { seat && (
192+ < Text size = "1" style = { { color : "var(--gray-9)" } } >
193+ { planLabel } Plan
194+ </ Text >
195+ ) }
196+ </ Flex >
197+ </ Flex >
198+ ) }
199+
148200 < button
149201 type = "button"
150202 className = "mt-2 flex cursor-pointer items-center gap-2 border-0 bg-transparent px-3 py-2 text-left text-[13px] text-gray-11 transition-colors hover:bg-gray-3"
@@ -166,59 +218,84 @@ export function SettingsDialog() {
166218 ) ) }
167219 </ div >
168220 </ ScrollArea >
221+
222+ { isAuthenticated && (
223+ < button
224+ type = "button"
225+ className = "flex cursor-pointer items-center gap-2 border-0 border-gray-5 border-t bg-transparent px-3 py-2.5 text-left font-mono text-[12px] text-gray-9 transition-colors hover:bg-gray-3 hover:text-gray-11"
226+ onClick = { ( ) => useAuthStore . getState ( ) . logout ( ) }
227+ >
228+ < SignOut size = { 14 } />
229+ < span > Sign out</ span >
230+ </ button >
231+ ) }
169232 </ div >
170233
171- < div className = "relative flex flex-1 justify-center overflow-hidden pt-8" >
172- < svg
173- aria-hidden = "true"
174- style = { {
175- position : "absolute" ,
176- bottom : 0 ,
177- left : 0 ,
178- width : "100%" ,
179- height : "100%" ,
180- pointerEvents : "none" ,
181- opacity : 0.4 ,
182- maskImage : "linear-gradient(to top, black 0%, transparent 100%)" ,
183- WebkitMaskImage :
184- "linear-gradient(to top, black 0%, transparent 100%)" ,
185- } }
186- >
187- < defs >
188- < pattern
189- id = "settings-dot-pattern"
190- patternUnits = "userSpaceOnUse"
191- width = "8"
192- height = "8"
193- >
194- < circle cx = "0" cy = "0" r = "1" fill = "var(--gray-6)" />
195- < circle cx = "0" cy = "8" r = "1" fill = "var(--gray-6)" />
196- < circle cx = "8" cy = "8" r = "1" fill = "var(--gray-6)" />
197- < circle cx = "8" cy = "0" r = "1" fill = "var(--gray-6)" />
198- < circle cx = "4" cy = "4" r = "1" fill = "var(--gray-6)" />
199- </ pattern >
200- </ defs >
201- < rect width = "100%" height = "100%" fill = "url(#settings-dot-pattern)" />
202- </ svg >
203- < ScrollArea
234+ < div className = "relative flex flex-1 flex-col overflow-hidden" >
235+ < div
236+ className = "drag"
204237 style = { {
205- height : "100%" ,
206- width : "100%" ,
238+ height : 36 ,
239+ flexShrink : 0 ,
240+ borderBottom : "1px solid var(--gray-6)" ,
207241 } }
208- >
209- < Box
210- p = "6"
211- mx = "auto"
212- style = { { position : "relative" , zIndex : 1 , maxWidth : "800px" } }
242+ />
243+ < div className = "relative flex flex-1 justify-center overflow-hidden" >
244+ < svg
245+ aria-hidden = "true"
246+ style = { {
247+ position : "absolute" ,
248+ bottom : 0 ,
249+ left : 0 ,
250+ width : "100%" ,
251+ height : "100%" ,
252+ pointerEvents : "none" ,
253+ opacity : 0.4 ,
254+ maskImage : "linear-gradient(to top, black 0%, transparent 100%)" ,
255+ WebkitMaskImage :
256+ "linear-gradient(to top, black 0%, transparent 100%)" ,
257+ } }
213258 >
214- < Flex direction = "column" gap = "4" >
215- < Text size = "4" weight = "medium" >
216- { CATEGORY_TITLES [ activeCategory ] }
217- </ Text >
218- < ActiveComponent />
219- </ Flex >
220- </ Box >
221- </ ScrollArea >
259+ < defs >
260+ < pattern
261+ id = "settings-dot-pattern"
262+ patternUnits = "userSpaceOnUse"
263+ width = "8"
264+ height = "8"
265+ >
266+ < circle cx = "0" cy = "0" r = "1" fill = "var(--gray-6)" />
267+ < circle cx = "0" cy = "8" r = "1" fill = "var(--gray-6)" />
268+ < circle cx = "8" cy = "8" r = "1" fill = "var(--gray-6)" />
269+ < circle cx = "8" cy = "0" r = "1" fill = "var(--gray-6)" />
270+ < circle cx = "4" cy = "4" r = "1" fill = "var(--gray-6)" />
271+ </ pattern >
272+ </ defs >
273+ < rect
274+ width = "100%"
275+ height = "100%"
276+ fill = "url(#settings-dot-pattern)"
277+ />
278+ </ svg >
279+ < ScrollArea
280+ style = { {
281+ height : "100%" ,
282+ width : "100%" ,
283+ } }
284+ >
285+ < Box
286+ p = "6"
287+ mx = "auto"
288+ style = { { position : "relative" , zIndex : 1 , maxWidth : "800px" } }
289+ >
290+ < Flex direction = "column" gap = "4" >
291+ < Text size = "4" weight = "medium" >
292+ { CATEGORY_TITLES [ activeCategory ] }
293+ </ Text >
294+ < ActiveComponent />
295+ </ Flex >
296+ </ Box >
297+ </ ScrollArea >
298+ </ div >
222299 </ div >
223300 </ div >
224301 ) ;
0 commit comments