Skip to content

Commit 16d96f1

Browse files
Merge pull request #21 from browserstack/new_demo_app_fixes
Fixes
2 parents 8d1ba44 + 1c28d39 commit 16d96f1

File tree

6 files changed

+197
-85
lines changed

6 files changed

+197
-85
lines changed

.github/workflows/static.yml

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22
name: Deploy static content to Pages
33

44
on:
5-
# Runs on pushes targeting the default branch
65
push:
7-
branches: ["demo_app_v2"]
6+
branches: ["main", "demo_app_v1", "demo_app_v2", "demo_app_v3", "demo_app_v4", "demo_app_v5"]
87

98
# Allows you to run this workflow manually from the Actions tab
109
workflow_dispatch:
@@ -31,13 +30,59 @@ jobs:
3130
steps:
3231
- name: Checkout
3332
uses: actions/checkout@v4
33+
34+
- name: Setup Node.js
35+
uses: actions/setup-node@v4
36+
with:
37+
node-version: '18'
38+
39+
- name: Install dependencies
40+
run: |
41+
if [ -f package-lock.json ]; then npm ci; else npm install; fi
42+
43+
- name: Determine deploy subpath
44+
id: vars
45+
run: |
46+
BRANCH=${GITHUB_REF#refs/heads/}
47+
# Default folder for main is root (no vX prefix). For demo branches map to v1..v5
48+
case "$BRANCH" in
49+
demo_app_v1) SUBPATH="v1";;
50+
demo_app_v2) SUBPATH="v2";;
51+
demo_app_v3) SUBPATH="v3";;
52+
demo_app_v4) SUBPATH="v4";;
53+
demo_app_v5) SUBPATH="v5";;
54+
main) SUBPATH="";;
55+
*) SUBPATH="";;
56+
esac
57+
echo "subpath=$SUBPATH" >> $GITHUB_OUTPUT
58+
59+
- name: Build
60+
env:
61+
BASE_PATH: ${{ steps.vars.outputs.subpath }}
62+
APP_BASE: browserstack-demo-app
63+
run: |
64+
# Compute a single deploy base that always ends with a trailing slash
65+
if [ -n "$BASE_PATH" ]; then
66+
DEPLOY_BASE="/${APP_BASE}/${BASE_PATH}/"
67+
else
68+
DEPLOY_BASE="/${APP_BASE}/"
69+
fi
70+
71+
# Export to the build-tool env names expected by the project
72+
export PUBLIC_URL="$DEPLOY_BASE"
73+
export VITE_BASE_PATH="$DEPLOY_BASE"
74+
echo "Building with DEPLOY_BASE=$DEPLOY_BASE"
75+
76+
npm run build
77+
3478
- name: Setup Pages
3579
uses: actions/configure-pages@v5
36-
- name: Upload artifact
80+
81+
- name: Upload build artifact
3782
uses: actions/upload-pages-artifact@v3
3883
with:
39-
# Upload entire repository
40-
path: '.'
84+
path: ./build
85+
4186
- name: Deploy to GitHub Pages
4287
id: deployment
4388
uses: actions/deploy-pages@v4

package-lock.json

Lines changed: 53 additions & 46 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,6 @@
8686
"tailwindcss": "^3.4.11",
8787
"typescript": "^5.5.3",
8888
"typescript-eslint": "^8.0.1",
89-
"vite": "^5.4.1"
89+
"vite": "^5.4.21"
9090
}
9191
}

public/404.html

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,24 @@
33
<head>
44
<meta charset="UTF-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6-
<title>Redirecting...</title>
6+
<title>Loading...</title>
77
<script>
8-
// Single Page Application redirect for GitHub Pages
9-
// This redirects all routes to index.html so React Router can handle them
10-
const pathSegmentsToKeep = 1;
11-
const l = window.location;
12-
l.replace(
13-
l.protocol + '//' + l.hostname + (l.port ? ':' + l.port : '') +
14-
l.pathname.split('/').slice(0, 1 + pathSegmentsToKeep).join('/') +
15-
'/?/' + l.pathname.slice(1).split('/').slice(pathSegmentsToKeep).join('/').replace(/&/g, '~and~') +
16-
(l.search ? '&' + l.search.slice(1).replace(/&/g, '~and~') : '') +
17-
l.hash
18-
);
8+
// Surge serves 404.html for unknown routes unless a 200 fallback is provided.
9+
// Instead of mutating the URL (which produced /?/… redirects), load the main
10+
// SPA shell in-place so React Router can hydrate the correct route.
11+
fetch('/index.html', { credentials: 'same-origin' })
12+
.then((response) => response.text())
13+
.then((html) => {
14+
document.open();
15+
document.write(html);
16+
document.close();
17+
})
18+
.catch(() => {
19+
window.location.replace('/');
20+
});
1921
</script>
2022
</head>
2123
<body>
22-
<p>Redirecting to the app...</p>
24+
<p>Loading the application…</p>
2325
</body>
2426
</html>

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

0 commit comments

Comments
 (0)