Skip to content

Commit 307579a

Browse files
authored
Merge pull request #53 from aws-samples/feature/cloudscape-ui-improvements
Feature/cloudscape UI improvements
2 parents a28c760 + 6237419 commit 307579a

File tree

8 files changed

+715
-232
lines changed

8 files changed

+715
-232
lines changed

src/components/Bot.tsx

Lines changed: 89 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,91 @@
1-
export function Bot(props: any) {
2-
console.log(props);
1+
import { useState } from 'react';
2+
import {
3+
Box,
4+
Button,
5+
Container,
6+
Header,
7+
SpaceBetween,
8+
Textarea,
9+
StatusIndicator
10+
} from "@cloudscape-design/components";
11+
12+
interface BotProps {
13+
transcript?: string;
14+
}
15+
16+
export function Bot({ transcript }: BotProps) {
17+
const [query, setQuery] = useState('');
18+
const [response, setResponse] = useState('');
19+
const [isLoading, setIsLoading] = useState(false);
20+
21+
const handleAskAI = async () => {
22+
if (!query.trim()) return;
23+
24+
setIsLoading(true);
25+
try {
26+
// TODO: Implement AI assistant functionality
27+
// This will be connected to AWS Bedrock in the workshop
28+
setTimeout(() => {
29+
setResponse("AI assistant functionality will be implemented during the workshop using AWS Bedrock.");
30+
setIsLoading(false);
31+
}, 1000);
32+
} catch (error) {
33+
console.error('Error asking AI:', error);
34+
setResponse("Sorry, I couldn't process your request at the moment.");
35+
setIsLoading(false);
36+
}
37+
};
38+
339
return (
4-
<div>
5-
<h3>Ask AI assistant</h3>
6-
<p>To be implemented...</p>
7-
</div>
40+
<Container
41+
header={
42+
<Header
43+
variant="h3"
44+
description="Ask questions about this video content"
45+
>
46+
Ask AI Assistant
47+
</Header>
48+
}
49+
>
50+
<SpaceBetween size="s">
51+
<Textarea
52+
placeholder="Ask a question about this video content..."
53+
value={query}
54+
onChange={({ detail }) => setQuery(detail.value)}
55+
rows={3}
56+
/>
57+
58+
<Box>
59+
<Button
60+
variant="primary"
61+
onClick={handleAskAI}
62+
disabled={!query.trim() || isLoading}
63+
loading={isLoading}
64+
iconName="gen-ai"
65+
>
66+
Ask AI
67+
</Button>
68+
</Box>
69+
70+
{response && (
71+
<Box
72+
padding="m"
73+
color="text-body-default"
74+
>
75+
<SpaceBetween size="xs">
76+
<StatusIndicator type="info">
77+
AI Response
78+
</StatusIndicator>
79+
<div style={{
80+
lineHeight: '1.5',
81+
wordBreak: 'break-word'
82+
}}>
83+
{response}
84+
</div>
85+
</SpaceBetween>
86+
</Box>
87+
)}
88+
</SpaceBetween>
89+
</Container>
890
);
9-
}
91+
}

src/components/ClassCatalog.tsx

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,18 +71,30 @@ const ClassCatalog = ({
7171
}
7272
}
7373
>
74-
{item.name}
74+
<div style={{
75+
wordBreak: 'break-word',
76+
lineHeight: '1.4'
77+
}}>
78+
{item.name}
79+
</div>
7580
</Link>
7681
),
7782
sections: [
7883
{
7984
id: "image",
80-
content: item => (<img src={item.image || '#'} alt={item.name} width='100%' />)
85+
content: item => (<img src={item.image || '#'} alt={item.name} width='100%' style={{ borderRadius: '4px' }} />)
8186
},
8287
{
8388
id: "description",
8489
header: "Description",
85-
content: item => item.description
90+
content: item => (
91+
<div style={{
92+
wordBreak: 'break-word',
93+
lineHeight: '1.5'
94+
}}>
95+
{item.description}
96+
</div>
97+
)
8698
},
8799
{
88100
id: 'state',

src/components/CommentForm.tsx

Lines changed: 47 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import {
44
Button,
55
Container,
66
Form,
7-
Grid,
87
Modal,
98
SpaceBetween,
109
Textarea,
10+
Header,
1111
} from "@cloudscape-design/components";
1212
import LoadingBar from "@cloudscape-design/chat-components/loading-bar";
1313
import { generateClient } from 'aws-amplify/data';
@@ -112,76 +112,74 @@ export const CommentForm = ({
112112
return (
113113
<form onSubmit={submitHandler}>
114114
<Form>
115-
<SpaceBetween size="m">
116-
<Box>
117-
<Button
118-
formAction="none"
119-
onClick={generateSummarization}
120-
iconName="gen-ai"
121-
disabled={isGenerating}
122-
loading={isGenerating}
123-
>
124-
Summarize
125-
</Button>
126-
</Box>
127-
128-
{isGenerating && (
129-
<Container>
130-
<Box
131-
margin={{ bottom: "xs", left: "l" }}
132-
color="text-body-secondary"
115+
<SpaceBetween size="l">
116+
<SpaceBetween size="s">
117+
<Box>
118+
<Button
119+
formAction="none"
120+
onClick={generateSummarization}
121+
iconName="gen-ai"
122+
disabled={isGenerating}
123+
loading={isGenerating}
133124
>
134-
Generating summary
125+
Summarize Comments
126+
</Button>
127+
</Box>
128+
129+
{isGenerating && (
130+
<Box>
131+
<SpaceBetween size="xs">
132+
<Box
133+
color="text-body-secondary"
134+
fontSize="body-s"
135+
>
136+
Generating AI summary...
137+
</Box>
138+
<LoadingBar variant="gen-ai" />
139+
</SpaceBetween>
135140
</Box>
136-
<LoadingBar variant="gen-ai" />
137-
</Container>
138-
)}
141+
)}
139142

140-
<Box>
141143
<Box
142-
variant="pre"
143-
padding="s"
144+
padding="m"
145+
color={summary && summary !== "Generated summary will appear here." ? "text-body-default" : "text-body-secondary"}
144146
fontSize="body-m"
145-
color="text-body-secondary"
146147
>
147148
<div
148149
style={{
149150
whiteSpace: 'pre-wrap',
150151
wordWrap: 'break-word',
152+
lineHeight: '1.5',
153+
border: '1px solid #e9ebed',
154+
borderRadius: '8px',
155+
padding: '12px',
156+
backgroundColor: '#fafbfc'
151157
}}
152158
>
153159
<NewLineToBr>{summary || "Generated summary will appear here."}</NewLineToBr>
154160
</div>
155161
</Box>
156-
</Box>
162+
</SpaceBetween>
157163

158-
<hr style={{ width: '100%', margin: '20px 0' }} />
159-
160-
<Grid disableGutters gridDefinition={[{ colspan: 10 }, { colspan: 2 }]}>
164+
<SpaceBetween size="s">
165+
<Header variant="h4">Add Comment</Header>
161166
<Textarea
162-
placeholder="Enter your comments here."
167+
placeholder="Share your thoughts about this class..."
163168
onChange={({ detail }) => setPost(detail.value)}
164169
value={post}
165-
rows={post.split(/\r\n|\r|\n/).length}
170+
rows={Math.max(3, post.split(/\r\n|\r|\n/).length)}
166171
/>
172+
167173
<Box float="right">
168-
<SpaceBetween direction="horizontal" size="xs">
169-
<Button
170-
formAction="none"
171-
iconName="undo"
172-
variant="icon"
173-
onClick={cancelHandler}
174-
disabled={isGenerating}
175-
/>
176-
<Button
177-
formAction="submit"
178-
iconName="upload"
179-
variant="icon"
180-
disabled={isGenerating}
181-
/>
182-
</SpaceBetween>
174+
<Button
175+
formAction="submit"
176+
variant="primary"
177+
disabled={isGenerating || !post.trim()}
178+
>
179+
Post Comment
180+
</Button>
183181
</Box>
184-
</Grid>
182+
</SpaceBetween>
185183
</SpaceBetween>
186184

187185
<Modal

src/components/CommentItem.tsx

Lines changed: 45 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,26 @@ import {
55
Modal,
66
SpaceBetween,
77
TextContent,
8+
Container,
9+
StatusIndicator
810
} from "@cloudscape-design/components";
911
import moment from 'moment';
1012
import { NewLineToBr } from './utils/NewLineToBr';
1113

1214
export const NoComment = () => (
1315
<Box
14-
padding={{ bottom: "s" }}
15-
fontSize="heading-s"
16+
padding="l"
1617
textAlign="center"
17-
color="inherit"
18+
color="text-body-secondary"
1819
>
19-
<b>No Contents</b>
20+
<SpaceBetween size="s" alignItems="center">
21+
<StatusIndicator type="info">
22+
No comments yet
23+
</StatusIndicator>
24+
<TextContent>
25+
<p>Be the first to share your thoughts about this class!</p>
26+
</TextContent>
27+
</SpaceBetween>
2028
</Box>
2129
);
2230

@@ -47,36 +55,40 @@ export const Comment = ({
4755
};
4856

4957
return (
50-
<Box
51-
padding="s"
52-
>
53-
<SpaceBetween direction="vertical" size="xs">
54-
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
55-
<TextContent>
56-
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
57-
<Box variant="small" color="text-body-secondary">
58-
{moment(comment.updatedAt).fromNow()}
59-
</Box>
60-
<Button
61-
iconName="remove"
62-
variant="icon"
63-
onClick={() => setConfirmVisible(true)}
64-
/>
65-
</div>
66-
</TextContent>
67-
</div>
68-
69-
<Box>
70-
<NewLineToBr>{comment.content || ''}</NewLineToBr>
71-
</Box>
72-
</SpaceBetween>
58+
<div style={{
59+
padding: '12px 0',
60+
borderBottom: '1px solid #eee'
61+
}}>
62+
<div style={{
63+
fontSize: '13px',
64+
color: '#666',
65+
marginBottom: '4px',
66+
display: 'flex',
67+
justifyContent: 'space-between',
68+
alignItems: 'center'
69+
}}>
70+
<span>{moment(comment.updatedAt).fromNow()}</span>
71+
<Button
72+
iconName="remove"
73+
variant="icon"
74+
onClick={() => setConfirmVisible(true)}
75+
ariaLabel="Delete"
76+
/>
77+
</div>
78+
<div style={{
79+
fontSize: '14px',
80+
lineHeight: '1.4',
81+
wordBreak: 'break-word'
82+
}}>
83+
<NewLineToBr>{comment.content || ''}</NewLineToBr>
84+
</div>
7385

7486
<Modal
7587
onDismiss={() => setConfirmVisible(false)}
7688
visible={confirmVisible}
7789
closeAriaLabel="Close modal"
7890
size="small"
79-
header="Delete Confirmation"
91+
header="Delete Comment"
8092
footer={
8193
<Box float="right">
8294
<SpaceBetween direction="horizontal" size="xs">
@@ -97,8 +109,10 @@ export const Comment = ({
97109
</Box>
98110
}
99111
>
100-
Are you sure to delete the message?
112+
<TextContent>
113+
<p>Are you sure you want to delete this comment? This action cannot be undone.</p>
114+
</TextContent>
101115
</Modal>
102-
</Box>
116+
</div>
103117
);
104-
};
118+
};

0 commit comments

Comments
 (0)