@@ -28,7 +28,7 @@ pub fn DashboardPage() -> impl IntoView {
2828 Ok ( resp) => {
2929 if resp. ok ( ) {
3030 if let Ok ( u) = resp. json :: < User > ( ) . await {
31- web_sys :: console :: log_1 ( & JsValue :: from_str ( & format ! ( "User authenticated: {}" , u . login ) ) ) ;
31+ // user authenticated
3232 set_user. set ( Some ( u. clone ( ) ) ) ;
3333
3434 let proj_url = format ! ( "{}/api/my-projects" , api_base( ) ) ;
@@ -44,14 +44,14 @@ pub fn DashboardPage() -> impl IntoView {
4444 set_projects. set ( projs) ;
4545 set_error. set ( None ) ;
4646 } else {
47- set_error. set ( Some ( "Failed to parse projects " . to_string ( ) ) ) ;
47+ set_error. set ( Some ( "Failed to parse project list " . to_string ( ) ) ) ;
4848 }
4949 } else {
50- set_error. set ( Some ( "Failed to fetch projects " . to_string ( ) ) ) ;
50+ set_error. set ( Some ( "Failed to fetch deployments " . to_string ( ) ) ) ;
5151 }
5252 }
5353 Err ( _) => {
54- set_error. set ( Some ( "Network error" . to_string ( ) ) ) ;
54+ set_error. set ( Some ( "Network error connecting to API " . to_string ( ) ) ) ;
5555 }
5656 }
5757 set_loading. set ( false ) ;
@@ -62,7 +62,7 @@ pub fn DashboardPage() -> impl IntoView {
6262 }
6363 Err ( _) => {
6464 set_loading. set ( false ) ;
65- set_error. set ( Some ( "Failed to authenticate " . to_string ( ) ) ) ;
65+ set_error. set ( Some ( "Authentication check failed " . to_string ( ) ) ) ;
6666 }
6767 }
6868 } ) ;
@@ -84,29 +84,22 @@ pub fn DashboardPage() -> impl IntoView {
8484 spawn_local ( async move {
8585 let encoded_query = js_sys:: encode_uri_component ( & query_clone) . to_string ( ) ;
8686 let search_url = format ! ( "{}/api/search-projects?q={}" , api_base( ) , encoded_query) ;
87- web_sys :: console :: log_1 ( & JsValue :: from_str ( & format ! ( "Searching for: {}" , search_url ) ) ) ;
87+
8888 match Request :: get ( & search_url)
8989 . credentials ( RequestCredentials :: Include )
9090 . send ( )
9191 . await
9292 {
9393 Ok ( resp) => {
94- web_sys:: console:: log_1 ( & JsValue :: from_str ( & format ! ( "Search response status: {}" , resp. status( ) ) ) ) ;
9594 if resp. ok ( ) {
9695 if let Ok ( results) = resp. json :: < Vec < ProjectSummary > > ( ) . await {
97- web_sys:: console:: log_1 ( & JsValue :: from_str ( & format ! ( "Found {} results" , results. len( ) ) ) ) ;
9896 set_search_results. set ( results) ;
9997 set_show_suggestions. set ( true ) ;
100- } else {
101- web_sys:: console:: log_1 ( & JsValue :: from_str ( "Failed to parse search results JSON" ) ) ;
10298 }
103- } else {
104- let err_text = resp. text ( ) . await . unwrap_or_default ( ) ;
105- web_sys:: console:: log_1 ( & JsValue :: from_str ( & format ! ( "Search failed: {}" , err_text) ) ) ;
10699 }
107100 }
108101 Err ( e) => {
109- web_sys:: console:: log_1 ( & JsValue :: from_str ( & format ! ( "Search network error: {:?}" , e) ) ) ;
102+ web_sys:: console:: log_1 ( & JsValue :: from_str ( & format ! ( "Search error: {:?}" , e) ) ) ;
110103 }
111104 }
112105 } ) ;
@@ -151,10 +144,10 @@ pub fn DashboardPage() -> impl IntoView {
151144 <span style="color: var(--text-main); font-weight: 500;" >{ u. login. clone( ) } </span>
152145 </div>
153146 <a href=format!( "{}/auth/logout" , api_base( ) )
154- class="btn-primary btn-logout"
155- rel="external"
156- style="text-decoration: none; font-size: 0.9rem;" >
157- "Logout"
147+ class="btn-primary btn-logout"
148+ rel="external"
149+ style="text-decoration: none; font-size: 0.9rem;" >
150+ "Logout"
158151 </a>
159152 } . into_view( ) ,
160153 None => view! {
@@ -175,8 +168,8 @@ pub fn DashboardPage() -> impl IntoView {
175168 <div class="dashboard-container" >
176169 <div class="dashboard-hero" >
177170 <div class="hero-content" >
178- <h1 class="hero-title" >"Dream it, Build it. " </h1>
179- <p class="hero-subtitle" >"Create and manage your interactive CLI projects " </p>
171+ <h1 class="hero-title" >"Workspace Overview " </h1>
172+ <p class="hero-subtitle" >"Manage your interactive sandboxes, monitor deployments, and publish new snapshots. " </p>
180173 <DashboardSearch
181174 search_input=search_input
182175 set_search_input=set_search_input
@@ -191,9 +184,9 @@ pub fn DashboardPage() -> impl IntoView {
191184
192185 <div class="dashboard-section" >
193186 <div class="section-header" >
194- <h2>"Your Projects " </h2>
187+ <h2>"Active Deployments " </h2>
195188 <A href="/new" class="btn-primary" >
196- "+ New Project "
189+ "+ Initialize Environment "
197190 </A >
198191 </div>
199192
@@ -211,8 +204,8 @@ pub fn DashboardPage() -> impl IntoView {
211204 } ,
212205 ( None , false ) => view! {
213206 <div style="display: flex; height: calc(100vh - 60px); justify-content: center; align-items: center; flex-direction: column; gap: 20px;" >
214- <h2 style="color: var(--text-main);" >"Welcome to TryCli Studio" </h2>
215- <p style="color: var(--text-muted);" >"Please sign in to start creating interactive demos ." </p>
207+ <h2 style="color: var(--text-main);" >"TryCli Studio Session Expired " </h2>
208+ <p style="color: var(--text-muted);" >"Please authenticate via GitHub to access your workspace ." </p>
216209 </div>
217210 } . into_view( ) ,
218211 _ => view! {
@@ -241,7 +234,7 @@ fn DashboardSearch(
241234 <div class="input-hero-wrapper" style="position: relative;" >
242235 <input type ="text"
243236 class="input-hero"
244- placeholder="Search or create a new project ..."
237+ placeholder="Search repositories or initialize a new sandbox ..."
245238 value=search_input. get( )
246239 on: input=handle_search_input
247240 on: focus=move |_| {
@@ -265,22 +258,22 @@ fn DashboardSearch(
265258 let navigate_fn = nav. clone( ) ;
266259
267260 view! {
268- <div style="position: absolute; top: 100%; left: 0; right: 0; background: var(--bg-main ); border: 1px solid var(--border); border-top: none; border-radius: 0 0 8px 8px; max-height: 300px; overflow-y: auto; z-index: 10;" >
261+ <div style="position: absolute; top: 100%; left: 0; right: 0; background: var(--bg-panel ); border: 1px solid var(--border); border-top: none; border-radius: 0 0 8px 8px; max-height: 300px; overflow-y: auto; z-index: 10; box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.5) ;" >
269262 { if results. is_empty( ) && !input_val. is_empty( ) {
270263 let input_val_copy = input_val. clone( ) ;
271264 let input_val_display = input_val. clone( ) ;
272265 view! {
273266 <div style="padding: 16px; color: var(--text-muted);" >
274- <p style="margin: 0 0 8px 0;" >"No project found." </p>
267+ <p style="margin: 0 0 8px 0; font-size: 0.9rem; " >"No existing environment found." </p>
275268 <button class="btn-primary"
276269 style="font-size: 0.9rem; padding: 8px 12px; width: 100%; text-align: left;"
277270 on: click=move |_| {
278- set_show_suggestions. set( false ) ;
279- set_search_input. set( String :: new( ) ) ;
280- let encoded_name = js_sys:: encode_uri_component( & input_val_copy) . to_string( ) ;
281- navigate_fn( & format!( "/new?name={}" , encoded_name) , Default :: default ( ) ) ;
282- } >
283- { format!( "Create project '{}'?" , input_val_display) }
271+ set_show_suggestions. set( false ) ;
272+ set_search_input. set( String :: new( ) ) ;
273+ let encoded_name = js_sys:: encode_uri_component( & input_val_copy) . to_string( ) ;
274+ navigate_fn( & format!( "/new?name={}" , encoded_name) , Default :: default ( ) ) ;
275+ } >
276+ { format!( "Initialize repository '{}'?" , input_val_display) }
284277 </button>
285278 </div>
286279 } . into_view( )
@@ -296,13 +289,13 @@ fn DashboardSearch(
296289 let proj_image = proj. image_tag. clone( ) ;
297290 view! {
298291 <a href=format!( "/{}/{}" , login, proj_slug. clone( ) )
299- style="display: block; padding: 12px 16px; color: var(--text-main); text-decoration: none; border-bottom: 1px solid var(--bg-dark ); cursor: pointer;"
292+ style="display: block; padding: 12px 16px; color: var(--text-main); text-decoration: none; border-bottom: 1px solid rgba(255, 255, 255, 0.05 ); cursor: pointer; transition: background 0.2s ;"
300293 on: click=move |_| {
301294 set_show_suggestions. set( false ) ;
302295 set_search_input. set( String :: new( ) ) ;
303296 } >
304- <div style="font-weight: 500 ;" >{ proj_slug} </div>
305- <div style="font-size: 0.85rem ; color: var(--text-muted);" >{ proj_image} </div>
297+ <div style="font-weight: 600; font-size: 0.95rem ;" >{ proj_slug} </div>
298+ <div style="font-size: 0.8rem ; color: var(--text-muted); font-family: var(--font-mono); margin-top: 2px ;" >{ proj_image} </div>
306299 </a>
307300 }
308301 }
@@ -326,18 +319,17 @@ fn DashboardProjectList(
326319 set_error : WriteSignal < Option < String > > ,
327320 set_loading : WriteSignal < bool > ,
328321 projects : ReadSignal < Vec < ProjectSummary > > ,
329- set_projects : WriteSignal < Vec < ProjectSummary > > , // < Receive Setter
322+ set_projects : WriteSignal < Vec < ProjectSummary > > ,
330323 user_login : Rc < String > ,
331324) -> impl IntoView {
332325
333326 // Handler for deletion logic
334327 let handle_delete = move |slug : String | {
335328 let prompt_text = format ! (
336- "⚠️ DESTRUCTIVE ACTION \n \n This will permanently delete the project '{}' and its Docker image .\n \n Please type the project name to confirm:" ,
329+ "⚠️ TERMINATE ENVIRONMENT \n \n This will permanently delete the snapshot '{}'. This action cannot be undone .\n \n Please type the environment name to confirm:" ,
337330 slug
338331 ) ;
339332
340- // FIX: Match against Ok(Some(input)) to handle the Result wrapper
341333 if let Ok ( Some ( input) ) = window ( ) . prompt_with_message ( & prompt_text) {
342334 if input == slug {
343335 let slug_clone = slug. clone ( ) ;
@@ -356,9 +348,9 @@ fn DashboardProjectList(
356348 set_projects. update ( |list| {
357349 list. retain ( |p| p. slug != slug_clone) ;
358350 } ) ;
359- let _ = window ( ) . alert_with_message ( "Project and Docker image deleted ." ) ;
351+ let _ = window ( ) . alert_with_message ( "Environment terminated and image removed ." ) ;
360352 } else {
361- let _ = window ( ) . alert_with_message ( "Failed to delete project. Check server logs ." ) ;
353+ let _ = window ( ) . alert_with_message ( "Failed to terminate environment ." ) ;
362354 }
363355 } ,
364356 Err ( _) => {
@@ -367,7 +359,7 @@ fn DashboardProjectList(
367359 }
368360 } ) ;
369361 } else {
370- let _ = window ( ) . alert_with_message ( "Project name mismatch. Deletion cancelled." ) ;
362+ let _ = window ( ) . alert_with_message ( "Name mismatch. Termination cancelled." ) ;
371363 }
372364 }
373365 } ;
@@ -381,7 +373,7 @@ fn DashboardProjectList(
381373 set_error. set( None ) ;
382374 set_loading. set( true ) ;
383375 } >
384- "Retry"
376+ "Retry Connection "
385377 </button>
386378 </div>
387379 } . into_view( ) ,
@@ -390,9 +382,9 @@ fn DashboardProjectList(
390382 if proj_list. is_empty( ) {
391383 view! {
392384 <div class="empty-state" >
393- <p class="empty-message" >"No projects yet. Create your first one! " </p>
385+ <p class="empty-message" >"No active environments. Initialize a new sandbox to start building. " </p>
394386 <A href="/new" class="btn-primary" >
395- "Create Project "
387+ "Initialize Environment "
396388 </A >
397389 </div>
398390 } . into_view( )
@@ -413,17 +405,17 @@ fn DashboardProjectList(
413405 <h3 class="card-title" >{ proj. slug. clone( ) } </h3>
414406 </div>
415407 <div class="card-body" >
416- <p class="card-meta" >"Image: " <code>{ proj. image_tag. clone( ) } </code></p>
408+ <p class="card-meta" >"Base Image: " <code>{ proj. image_tag. clone( ) } </code></p>
417409 </div>
418410 <div class="card-footer" style="display: flex;" >
419411 <A href=format!( "/{}/{}" , login, proj. slug)
420412 class="btn-card" >
421- "View "
413+ "Launch Studio "
422414 </A >
423415 <button
424416 class="btn-danger"
425417 on: click=move |_| handle_delete( delete_slug. clone( ) ) >
426- "Delete "
418+ "Terminate "
427419 </button>
428420 </div>
429421 </div>
0 commit comments