Skip to content

Commit 93858c2

Browse files
committed
fix: Address CodeRabbit review — sessionStorage fallback + semantic Footer link
1 parent 4216787 commit 93858c2

4 files changed

Lines changed: 57 additions & 21 deletions

File tree

src/components/Footer.jsx

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { FileText, WarningCircle, MapPin } from '@phosphor-icons/react';
99
import { SiYoutube, SiInstagram, SiTiktok } from 'react-icons/si';
1010
import { useState, useEffect } from 'react';
1111
import { useTranslation } from 'react-i18next';
12-
import { useNavigate } from 'react-router-dom';
12+
import { useNavigate, Link } from 'react-router-dom';
1313
import {
1414
GITHUB_REPO_NAME,
1515
GITHUB_REPO_OWNER,
@@ -288,15 +288,12 @@ function Footer() {
288288
© {currentYear} Bayan Flow. {t('footer.allRightsReserved')}
289289
</p>
290290
<div className="flex flex-wrap items-center justify-center gap-4">
291-
<motion.button
292-
type="button"
293-
onClick={() => handleLinkClick('/pro')}
291+
<Link
292+
to="/pro"
294293
className="text-xs text-text-secondary hover:text-[#3b82f6] transition-colors"
295-
whileHover={{ scale: 1.02 }}
296-
whileTap={{ scale: 0.98 }}
297294
>
298295
{t('footer.proPlan')}
299-
</motion.button>
296+
</Link>
300297
<motion.button
301298
type="button"
302299
onClick={() => handleLinkClick('/privacy')}

src/components/Footer.test.jsx

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
*/
66

77
import { describe, it, expect, vi, beforeEach } from 'vitest';
8-
import { renderWithI18n, screen, fireEvent } from '../test/testUtils';
8+
import { render, screen, fireEvent } from '@testing-library/react';
9+
import { MemoryRouter } from 'react-router-dom';
10+
import { I18nextProvider } from 'react-i18next';
911
import Footer from './Footer';
1012
import i18n from '../i18n';
1113

@@ -19,6 +21,16 @@ vi.mock('react-router-dom', async importOriginal => {
1921
};
2022
});
2123

24+
function renderFooter() {
25+
return render(
26+
<MemoryRouter>
27+
<I18nextProvider i18n={i18n}>
28+
<Footer />
29+
</I18nextProvider>
30+
</MemoryRouter>
31+
);
32+
}
33+
2234
describe('Footer', () => {
2335
beforeEach(async () => {
2436
mockNavigate.mockClear();
@@ -27,36 +39,42 @@ describe('Footer', () => {
2739
});
2840

2941
it('renders privacy and terms links', () => {
30-
renderWithI18n(<Footer />);
42+
renderFooter();
3143

3244
expect(screen.getByText(i18n.t('footer.privacy'))).toBeInTheDocument();
3345
expect(screen.getByText(i18n.t('footer.terms'))).toBeInTheDocument();
3446
});
3547

3648
it('navigates to privacy policy on click', () => {
37-
renderWithI18n(<Footer />);
49+
renderFooter();
3850

3951
fireEvent.click(screen.getByText(i18n.t('footer.privacy')));
4052
expect(mockNavigate).toHaveBeenCalledWith('/privacy');
4153
});
4254

4355
it('navigates to terms of use on click', () => {
44-
renderWithI18n(<Footer />);
56+
renderFooter();
4557

4658
fireEvent.click(screen.getByText(i18n.t('footer.terms')));
4759
expect(mockNavigate).toHaveBeenCalledWith('/terms');
4860
});
4961

5062
it('renders pro plan link', () => {
51-
renderWithI18n(<Footer />);
63+
renderFooter();
5264

53-
expect(screen.getByText(i18n.t('footer.proPlan'))).toBeInTheDocument();
65+
const link = screen.getByRole('link', {
66+
name: i18n.t('footer.proPlan'),
67+
});
68+
expect(link).toHaveAttribute('href', '/pro');
5469
});
5570

5671
it('navigates to pro page on click', () => {
57-
renderWithI18n(<Footer />);
72+
renderFooter();
5873

59-
fireEvent.click(screen.getByText(i18n.t('footer.proPlan')));
60-
expect(mockNavigate).toHaveBeenCalledWith('/pro');
74+
const link = screen.getByRole('link', {
75+
name: i18n.t('footer.proPlan'),
76+
});
77+
expect(link).toHaveAttribute('href', '/pro');
78+
fireEvent.click(link);
6179
});
6280
});

src/components/ProWaitlistBanner.jsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,11 @@ function ProWaitlistBannerContent({ source, pathname, inRouter }) {
2929
if (dismissedFlag == null) {
3030
const legacy = sessionStorage.getItem(WAITLIST_BANNER_DISMISSED_KEY);
3131
if (legacy != null) {
32-
localStorage.setItem(WAITLIST_BANNER_DISMISSED_KEY, legacy);
32+
try {
33+
localStorage.setItem(WAITLIST_BANNER_DISMISSED_KEY, legacy);
34+
} catch {
35+
// migration write failed, but we still have the legacy value
36+
}
3337
dismissedFlag = legacy;
3438
}
3539
}
@@ -60,7 +64,11 @@ function ProWaitlistBannerContent({ source, pathname, inRouter }) {
6064
try {
6165
localStorage.setItem(WAITLIST_BANNER_DISMISSED_KEY, '1');
6266
} catch {
63-
// ignore
67+
try {
68+
sessionStorage.setItem(WAITLIST_BANNER_DISMISSED_KEY, '1');
69+
} catch {
70+
// ignore
71+
}
6472
}
6573
setDismissed(true);
6674
window.dispatchEvent(new CustomEvent('bayan-flow:banner-dismissed'));

src/services/waitlistService.js

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,11 @@ export function persistWaitlistEmail(email) {
4747
try {
4848
localStorage.setItem(WAITLIST_EMAIL_STORAGE_KEY, email);
4949
} catch {
50-
// ignore quota / private mode
50+
try {
51+
sessionStorage.setItem(WAITLIST_EMAIL_STORAGE_KEY, email);
52+
} catch {
53+
// ignore quota / private mode
54+
}
5155
}
5256
}
5357

@@ -60,13 +64,22 @@ export function readStoredWaitlistEmail() {
6064
if (value == null) {
6165
const legacy = sessionStorage.getItem(WAITLIST_EMAIL_STORAGE_KEY);
6266
if (legacy != null) {
63-
localStorage.setItem(WAITLIST_EMAIL_STORAGE_KEY, legacy);
67+
try {
68+
localStorage.setItem(WAITLIST_EMAIL_STORAGE_KEY, legacy);
69+
} catch {
70+
// migration write failed, but we still have the legacy value
71+
}
6472
value = legacy;
6573
}
6674
}
6775
return value ? normalizeWaitlistEmail(value) : null;
6876
} catch {
69-
return null;
77+
try {
78+
const fallback = sessionStorage.getItem(WAITLIST_EMAIL_STORAGE_KEY);
79+
return fallback ? normalizeWaitlistEmail(fallback) : null;
80+
} catch {
81+
return null;
82+
}
7083
}
7184
}
7285

0 commit comments

Comments
 (0)