Skip to content

Commit 58584a6

Browse files
committed
Merge remote-tracking branch 'origin/demo_app_v2' into demo_app_v1
2 parents 93424ba + 5d6e9ba commit 58584a6

File tree

3 files changed

+79
-43
lines changed

3 files changed

+79
-43
lines changed

src/components/LoginForm.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const LoginForm: React.FC = () => {
1212
const [showPassword, setShowPassword] = useState(false);
1313
const [isLoading, setIsLoading] = useState(false);
1414
const [selectedUser, setSelectedUser] = useState<string>('');
15+
const [errorMessage, setErrorMessage] = useState<string | null>(null);
1516
const { login } = useUser();
1617
const navigate = useNavigate();
1718

@@ -23,15 +24,16 @@ const LoginForm: React.FC = () => {
2324
const matchedUser = userProfiles.find(u => u.email === email && u.password === password);
2425
if (!matchedUser) {
2526
setIsLoading(false);
26-
alert('Login failed. Please check your credentials.');
27+
setErrorMessage('Login failed. Please check your credentials.');
2728
return;
2829
}
2930
const success = await login(matchedUser.userId.toString(), email);
3031
setIsLoading(false);
3132
if (success) {
33+
setErrorMessage(null);
3234
navigate('/products');
3335
} else {
34-
alert('Login failed. Please check your credentials.');
36+
setErrorMessage('Login failed. Please check your credentials.');
3537
}
3638
};
3739

@@ -51,6 +53,14 @@ const LoginForm: React.FC = () => {
5153

5254
{/* Quick user selector keeps demo credentials handy */}
5355
<form onSubmit={handleSubmit} className="space-y-6">
56+
{errorMessage && (
57+
<div
58+
id="login-error"
59+
className="rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-sm font-medium text-red-700"
60+
>
61+
{errorMessage}
62+
</div>
63+
)}
5464
<div>
5565
<label className="block text-sm font-medium mb-2 text-gray-700">Quick Select User</label>
5666
<select

src/data/userProfiles.ts

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,4 @@
11
// Static user profile data for test/demo use
22
import { getAssetPath } from '../lib/assetUtils';
33

4-
export const userProfiles = [
5-
{
6-
userId: 1,
7-
email: 'demo1@example.com',
8-
password: 'Qw!@d..**~cwcw',
9-
name: 'Demo One',
10-
avatar: getAssetPath('/static/avatars/demo1.svg')
11-
},
12-
{
13-
userId: 2,
14-
email: 'demo2@example.com',
15-
password: '@qqwdSC1eEem__o12',
16-
name: 'Demo Two',
17-
avatar: getAssetPath('/static/avatars/demo2.svg')
18-
},
19-
{
20-
userId: 3,
21-
email: 'testuser@example.com',
22-
password: 'test!!1-23Z~ww',
23-
name: 'Test User',
24-
avatar: getAssetPath('/static/avatars/testuser.svg')
25-
}
26-
];
4+
export const userProfiles = [];

src/pages/Scenarios.tsx

Lines changed: 66 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,58 @@ import { Toaster } from '../components/ui/toaster';
88
const Scenarios: React.FC = () => {
99
const [toggleState, setToggleState] = useState(false);
1010
const [progressValue, setProgressValue] = useState(45);
11+
const [lastCopiedLink, setLastCopiedLink] = useState('');
1112
const toastStyles = 'border-2 shadow-lg rounded-lg px-4 py-3 font-semibold transition-all duration-200 bg-blue-100 border-blue-300 text-blue-800';
1213

14+
const showCopyToast = (description: string) =>
15+
toast({
16+
title: 'Link copied',
17+
description,
18+
className: toastStyles,
19+
duration: 800
20+
});
21+
22+
const fallbackCopyToClipboard = (value: string) => {
23+
const textarea = document.createElement('textarea');
24+
textarea.value = value;
25+
textarea.setAttribute('readonly', '');
26+
textarea.style.position = 'absolute';
27+
textarea.style.left = '-9999px';
28+
document.body.appendChild(textarea);
29+
textarea.select();
30+
try {
31+
document.execCommand('copy');
32+
} catch (error) {
33+
console.warn('Clipboard fallback failed', error);
34+
}
35+
document.body.removeChild(textarea);
36+
};
37+
38+
const handleCopyShareLink = () => {
39+
const text = document.getElementById('share-link')?.textContent?.trim();
40+
if (!text) {
41+
return;
42+
}
43+
44+
if (navigator.clipboard?.writeText) {
45+
navigator.clipboard
46+
.writeText(text)
47+
.then(() => {
48+
setLastCopiedLink(text);
49+
showCopyToast('The scenario URL is ready to share.');
50+
})
51+
.catch(() => {
52+
fallbackCopyToClipboard(text);
53+
setLastCopiedLink(text);
54+
showCopyToast('Copied using fallback clipboard support.');
55+
});
56+
} else {
57+
fallbackCopyToClipboard(text);
58+
setLastCopiedLink(text);
59+
showCopyToast('Copied using fallback clipboard support.');
60+
}
61+
};
62+
1363
return (
1464
<div className="min-h-screen py-8">
1565
<Toaster />
@@ -21,18 +71,18 @@ const Scenarios: React.FC = () => {
2171
</p>
2272
</div>
2373

24-
<div className="grid lg:grid-cols-2 gap-8">
74+
<div className="grid gap-8 md:grid-cols-1 lg:grid-cols-2">
2575
<Card className="bg-white p-8 rounded-xl shadow-lg">
2676
<div className="flex items-center gap-3 mb-6">
2777
<div className="p-2 bg-blue-100 text-blue-600 rounded-lg">
2878
<CheckCircle className="w-6 h-6" />
2979
</div>
3080
<div>
31-
<h3 className="text-xl font-bold">Form Field Target</h3>
32-
<p className="text-gray-600">Demonstrate how your flows handle predictable customer reference fields.</p>
81+
<h3 className="text-xl font-bold">Static ID Field</h3>
82+
<p className="text-gray-600">Demonstrate how your scripts store and reuse customer references.</p>
3383
</div>
3484
</div>
35-
<div className="space-y-2">
85+
<div className="space-y-4">
3686
<label htmlFor="static-id-field" className="text-sm font-medium text-gray-600">Customer reference</label>
3787
<input
3888
type="text"
@@ -92,7 +142,7 @@ const Scenarios: React.FC = () => {
92142
title: 'Demo notification',
93143
description: 'Content Description button clicked!',
94144
className: toastStyles,
95-
duration: 500
145+
duration: 5000
96146
})}
97147
>
98148
Submit
@@ -116,22 +166,20 @@ const Scenarios: React.FC = () => {
116166
</div>
117167
<button
118168
className="w-full py-3 px-4 rounded-lg font-medium transition-all bg-blue-600 hover:bg-blue-700 text-white"
119-
onClick={() => {
120-
const text = document.getElementById('share-link')?.textContent?.trim();
121-
if (text) {
122-
navigator.clipboard.writeText(text).then(() => {
123-
toast({
124-
title: 'Link copied',
125-
description: 'The scenario URL is ready to share.',
126-
className: toastStyles,
127-
duration: 3000
128-
});
129-
});
130-
}
131-
}}
169+
onClick={handleCopyShareLink}
132170
>
133171
Copy share link
134172
</button>
173+
{lastCopiedLink && (
174+
<div
175+
id="share-copy-result"
176+
className="mt-3 rounded-lg border border-blue-100 bg-blue-50 px-3 py-2 text-sm font-medium text-blue-700"
177+
aria-live="polite"
178+
data-automation="copy-result"
179+
>
180+
Last copied: <span className="font-mono">{lastCopiedLink}</span>
181+
</div>
182+
)}
135183
</div>
136184
</Card>
137185

0 commit comments

Comments
 (0)