diff --git a/src/app/release-notes/page.tsx b/src/app/release-notes/page.tsx
new file mode 100644
index 0000000..0c9a714
--- /dev/null
+++ b/src/app/release-notes/page.tsx
@@ -0,0 +1,19 @@
+import React, { lazy } from 'react';
+import LazyLoadingManager from '@/components/performance/LazyLoadingManager';
+
+const LazyReleaseNotes = lazy(() => import('@/components/shared/ReleaseNotes'));
+
+export default function ReleaseNotesPage() {
+ return (
+
+
+
+ What's New in TeachLink
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/index.ts b/src/components/index.ts
index b02e098..490b771 100644
--- a/src/components/index.ts
+++ b/src/components/index.ts
@@ -22,3 +22,4 @@ export { BulkImporter } from './BulkImporter';
export type { BulkImporterProps, TargetFieldDef } from './BulkImporter';
export { Tooltip } from './ui/Tooltip';
export type { TooltipProps, TooltipPlacement } from './ui/Tooltip';
+export * from './shared/ReleaseNotes';
diff --git a/src/components/shared/ReleaseNotes.test.tsx b/src/components/shared/ReleaseNotes.test.tsx
new file mode 100644
index 0000000..3108df9
--- /dev/null
+++ b/src/components/shared/ReleaseNotes.test.tsx
@@ -0,0 +1,24 @@
+import React from 'react';
+import { render, screen, waitFor } from '@testing-library/react';
+import '@testing-library/jest-dom';
+import ReleaseNotes from './ReleaseNotes';
+
+describe('ReleaseNotes', () => {
+ it('renders loading state initially', () => {
+ render();
+ expect(screen.getByTestId('loading-skeleton')).toBeInTheDocument();
+ });
+
+ it('renders release notes after loading', async () => {
+ render();
+
+ // Wait for the component to finish "fetching" (500ms mock delay)
+ await waitFor(() => {
+ expect(screen.getByText('Release Notes')).toBeInTheDocument();
+ }, { timeout: 1000 });
+
+ expect(screen.getByText('v1.2.0')).toBeInTheDocument();
+ expect(screen.getByText('v1.1.0')).toBeInTheDocument();
+ expect(screen.getByText('Added Lazy Loading support')).toBeInTheDocument();
+ });
+});
diff --git a/src/components/shared/ReleaseNotes.tsx b/src/components/shared/ReleaseNotes.tsx
new file mode 100644
index 0000000..eae7f0c
--- /dev/null
+++ b/src/components/shared/ReleaseNotes.tsx
@@ -0,0 +1,73 @@
+import React, { useState, useEffect } from 'react';
+
+export interface ReleaseNote {
+ version: string;
+ date: string;
+ changes: string[];
+}
+
+export const ReleaseNotes: React.FC = () => {
+ const [notes, setNotes] = useState([]);
+ const [loading, setLoading] = useState(true);
+
+ useEffect(() => {
+ // Simulate fetching release notes
+ const fetchNotes = async () => {
+ try {
+ // Mock data
+ const data: ReleaseNote[] = [
+ {
+ version: '1.2.0',
+ date: '2026-05-30',
+ changes: ['Added Lazy Loading support', 'Improved performance', 'Fixed bugs'],
+ },
+ {
+ version: '1.1.0',
+ date: '2026-05-15',
+ changes: ['Added Release Notes feature', 'Updated dependencies'],
+ },
+ ];
+
+ // Simulate network delay
+ await new Promise(resolve => setTimeout(resolve, 500));
+ setNotes(data);
+ } catch (error) {
+ console.error('Failed to fetch release notes:', error);
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ fetchNotes();
+ }, []);
+
+ if (loading) {
+ return ;
+ }
+
+ return (
+
+
Release Notes
+ {notes.length === 0 ? (
+
No release notes available.
+ ) : (
+
+ {notes.map((note) => (
+ -
+
+ v{note.version} ({note.date})
+
+
+ {note.changes.map((change, idx) => (
+ - {change}
+ ))}
+
+
+ ))}
+
+ )}
+
+ );
+};
+
+export default ReleaseNotes;