11import { useState , useRef , useEffect } from "react" ;
22import {
33 Container , SpaceBetween , Button , Box , Header ,
4- Textarea , ExpandableSection , Link , Badge , Spinner
4+ Textarea , ExpandableSection , Link , Badge , Spinner , ColumnLayout
55} from "@cloudscape-design/components" ;
66import { generateClient } from 'aws-amplify/data' ;
77import { Schema } from '../../amplify/data/resource' ;
@@ -409,101 +409,93 @@ export default function AgentSearch() {
409409 case 'course' :
410410 const thumbnail = courseThumbnails [ section . link ] || section . thumbnail ;
411411 return (
412- < Box
413- key = { index }
414- padding = "l"
415- variant = "div"
416- style = { {
417- border : '3px solid #d1d5db' ,
418- borderRadius : '16px' ,
419- backgroundColor : '#ffffff' ,
420- boxShadow : '0 4px 12px rgba(0,0,0,0.15)' ,
421- marginBottom : '24px' ,
422- marginTop : '16px' ,
423- position : 'relative'
424- } }
425- >
426- { courseNumber && (
427- < Box
428- style = { {
429- position : 'absolute' ,
430- top : '-12px' ,
431- left : '20px' ,
432- backgroundColor : '#ffffff' ,
433- borderRadius : '8px' ,
434- padding : '8px 16px' ,
435- fontSize : '24px' ,
436- fontWeight : 'bold' ,
437- boxShadow : '0 2px 8px rgba(0,0,0,0.2)' ,
438- zIndex : 1 ,
439- border : '2px solid #e9ebed'
440- } }
412+ < Container
413+ key = { index }
414+ header = {
415+ < Header
416+ variant = "h2"
417+ description = { `Instructor: ${ section . instructor } ` }
441418 >
442- 🎬 { courseNumber }
443- </ Box >
444- ) }
445- < SpaceBetween size = "s" >
419+ 🎬 Course { courseNumber } : { section . title }
420+ </ Header >
421+ }
422+ >
423+ < SpaceBetween size = "l" >
446424 { thumbnail && (
447425 < Link href = { section . link } external >
448426 < img
449427 src = { thumbnail }
450428 alt = { section . title }
451429 style = { {
452430 width : '100%' ,
453- maxWidth : '500px' ,
454- borderRadius : '8px' ,
455- cursor : 'pointer'
431+ maxWidth : '600px' ,
432+ borderRadius : '8px'
456433 } }
457434 />
458435 </ Link >
459436 ) }
460- < Header variant = "h4" > { section . title } </ Header >
461- < SpaceBetween size = "xs" direction = "horizontal" >
462- < Badge color = {
463- section . difficulty === 'beginner' ? 'green' :
464- section . difficulty === 'intermediate' ? 'blue' : 'red'
465- } >
466- { section . difficulty }
467- </ Badge >
468- < Box fontSize = "body-s" > Instructor: { section . instructor } </ Box >
469- </ SpaceBetween >
470- < Box fontSize = "body-s" > { section . description } </ Box >
471- < Box fontSize = "body-s" color = "text-status-info" >
472- 💡 { section . reason }
473- </ Box >
437+
438+ < ColumnLayout columns = { 2 } variant = "text-grid" >
439+ < div >
440+ < Box variant = "awsui-key-label" > Difficulty</ Box >
441+ < Badge color = {
442+ section . difficulty === 'beginner' ? 'green' :
443+ section . difficulty === 'intermediate' ? 'blue' : 'red'
444+ } >
445+ { section . difficulty . toUpperCase ( ) }
446+ </ Badge >
447+ </ div >
448+ < div >
449+ < Box variant = "awsui-key-label" > Instructor</ Box >
450+ < Box > { section . instructor } </ Box >
451+ </ div >
452+ </ ColumnLayout >
453+
454+ < div >
455+ < Box variant = "awsui-key-label" > Description</ Box >
456+ < Box > { section . description } </ Box >
457+ </ div >
458+
459+ < Container >
460+ < Box variant = "awsui-key-label" > 💡 Why this course?</ Box >
461+ < Box > { section . reason } </ Box >
462+ </ Container >
463+
464+ < Button href = { section . link } iconName = "external" target = "_blank" >
465+ View Course
466+ </ Button >
474467 </ SpaceBetween >
475- </ Box >
468+ </ Container >
476469 ) ;
477470
478471 case 'roadmap' :
479472 return (
480- < Box key = { index } >
481- < Header variant = "h4" > { section . title } </ Header >
482- < SpaceBetween size = "s" >
473+ < Container key = { index } header = { < Header variant = "h3" > { section . title } </ Header > } >
474+ < SpaceBetween size = "m" >
483475 { section . steps . map ( ( step , stepIndex ) => (
484- < Box key = { stepIndex } padding = "s" style = { { backgroundColor : '#f9f9f9' , borderRadius : '4px' } } >
485- < SpaceBetween size = "xs " >
486- < Header variant = "h5 " > { step . step } : { step . title } </ Header >
487- < Box fontSize = "body-s" > { step . description } </ Box >
476+ < Container key = { stepIndex } >
477+ < SpaceBetween size = "s " >
478+ < Header variant = "h4 " > { step . step } : { step . title } </ Header >
479+ < Box > { step . description } </ Box >
488480 { step . courses . length > 0 && (
489- < Box fontSize = "body-s" >
490- < strong > Related Courses:</ strong > { step . courses . join ( ', ' ) }
491- </ Box >
481+ < div >
482+ < Box variant = "awsui-key-label" > Related Courses</ Box >
483+ < Box > { step . courses . join ( ', ' ) } </ Box >
484+ </ div >
492485 ) }
493486 </ SpaceBetween >
494- </ Box >
487+ </ Container >
495488 ) ) }
496489 </ SpaceBetween >
497- </ Box >
490+ </ Container >
498491 ) ;
499492
500493 case 'list' :
501494 return (
502- < Box key = { index } >
503- < Header variant = "h4" > { section . title } </ Header >
495+ < Container key = { index } header = { < Header variant = "h3" > { section . title } </ Header > } >
504496 < SpaceBetween size = "xs" >
505497 { section . items . map ( ( item , itemIndex ) => (
506- < Box key = { itemIndex } margin = { { left : "s" } } >
498+ < Box key = { itemIndex } >
507499 • { item . link ? (
508500 < Link external href = { item . link } > { item . text } </ Link >
509501 ) : (
@@ -512,7 +504,7 @@ export default function AgentSearch() {
512504 </ Box >
513505 ) ) }
514506 </ SpaceBetween >
515- </ Box >
507+ </ Container >
516508 ) ;
517509
518510 default :
@@ -523,42 +515,27 @@ export default function AgentSearch() {
523515 const renderMessage = ( message : ChatMessage ) => {
524516 if ( message . type === 'user' ) {
525517 return (
526- < Box
527- key = { message . id }
528- padding = "m"
529- style = { {
530- backgroundColor : '#e3f2fd' ,
531- borderRadius : '8px' ,
532- marginLeft : '20%'
533- } }
534- >
518+ < Container key = { message . id } >
535519 < SpaceBetween size = "xs" >
536- < Box fontSize = "body-s" color = "text-status-info" > You</ Box >
520+ < Box variant = "awsui-key-label" > 👤 You</ Box >
537521 < Box > { message . content } </ Box >
538522 </ SpaceBetween >
539- </ Box >
523+ </ Container >
540524 ) ;
541525 }
542526
543527 return (
544- < Box
545- key = { message . id }
546- padding = "m"
547- style = { {
548- backgroundColor : '#f5f5f5' ,
549- borderRadius : '8px' ,
550- marginRight : '10%'
551- } }
552- >
553- < SpaceBetween size = "s" >
554- < Box fontSize = "body-s" color = "text-status-info" >
555- 🤖 Agent { streamingMessageId === message . id && (
556- < SpaceBetween size = "xs" direction = "horizontal" >
528+ < Container key = { message . id } >
529+ < SpaceBetween size = "m" >
530+ < SpaceBetween size = "xs" direction = "horizontal" alignItems = "center" >
531+ < Box variant = "awsui-key-label" > 🤖 AI Agent</ Box >
532+ { streamingMessageId === message . id && (
533+ < SpaceBetween size = "xs" direction = "horizontal" alignItems = "center" >
557534 < Spinner size = "small" />
558- < span > Generating response ...</ span >
535+ < Box fontSize = "body-s" color = "text-status-info" > typing ...</ Box >
559536 </ SpaceBetween >
560537 ) }
561- </ Box >
538+ </ SpaceBetween >
562539
563540 { message . traces && message . traces . length > 0 && (
564541 < ExpandableSection headerText = { `🔍 Processing Steps (${ message . traces . length } )` } variant = "container" >
@@ -572,9 +549,8 @@ export default function AgentSearch() {
572549 </ ExpandableSection >
573550 ) }
574551
575- { /* Render structured response if available */ }
576552 { message . parsedResponse ? (
577- < SpaceBetween size = "m " >
553+ < SpaceBetween size = "l " >
578554 { message . parsedResponse . sections . map ( ( section , index ) => {
579555 // Calculate course number
580556 const courseNumber = message . parsedResponse ! . sections
@@ -595,32 +571,21 @@ export default function AgentSearch() {
595571 </ Box >
596572 </ ExpandableSection >
597573 </ SpaceBetween >
598- </ Box >
574+ </ Container >
599575 ) ;
600576 } ;
601577
602578 return (
603579 < BaseAppLayout
604580 content = {
605- < div >
606- < style > { `
607- @keyframes fadeIn {
608- from { opacity: 0; transform: translateY(10px); }
609- to { opacity: 1; transform: translateY(0); }
610- }
611- @keyframes pulse {
612- 0%, 100% { opacity: 1; }
613- 50% { opacity: 0.7; }
614- }
615- ` } </ style >
616-
581+ < Container >
617582 < SpaceBetween size = "l" >
618- < Container >
619- < Header variant = "h1" > 🤖 Bedrock Agent Chat </ Header >
620- < Box fontSize = "body-s" color = "text-status-info" >
621- Session ID: { sessionId . current }
622- </ Box >
623- </ Container >
583+ < Header
584+ variant = "h1"
585+ description = "Ask questions and get AI-powered course recommendations"
586+ >
587+ 🤖 Bedrock Agent Chat
588+ </ Header >
624589
625590 { /* Chat History */ }
626591 { messages . length > 0 && (
@@ -696,6 +661,7 @@ export default function AgentSearch() {
696661 onClick = { handleSearch }
697662 loading = { loading }
698663 disabled = { ! query . trim ( ) }
664+ iconName = "send"
699665 >
700666 Send
701667 </ Button >
@@ -704,18 +670,15 @@ export default function AgentSearch() {
704670 setMessages ( [ ] ) ;
705671 sessionId . current = `session-${ Date . now ( ) } ` ;
706672 } }
673+ iconName = "refresh"
707674 >
708- New Session
675+ New Chat
709676 </ Button >
710677 </ SpaceBetween >
711-
712- < Box fontSize = "body-s" color = "text-status-info" >
713- Tip: Press Cmd+Enter (Mac) or Ctrl+Enter (Windows) to send
714- </ Box >
715678 </ SpaceBetween >
716679 </ Container >
717- </ SpaceBetween >
718- </ div >
680+ </ SpaceBetween >
681+ </ Container >
719682 }
720683 />
721684 ) ;
0 commit comments