Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@anthropic-ai/sdk": "^0.128.0",
"@profullstack/autoblog": "github:profullstack/autoblog#75e54af",
"@profullstack/emailer": "^1.0.3",
"@profullstack/footer": "latest",
"@profullstack/notifications": "0.1.0",
"@profullstack/stack": "^0.1.3",
"@profullstack/x402-gateway": "^0.7.0",
Expand Down
7 changes: 1 addition & 6 deletions apps/web/src/app/settings/page.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,6 @@ vi.mock('@/components/header-client', () => ({
HeaderClient: () => <header data-testid="header">Header</header>,
}));

// Mock Footer
vi.mock('@/components/footer', () => ({
Footer: () => <footer data-testid="footer">Footer</footer>,
}));

// Mock NotificationPreferences (uses fetch and service worker APIs)
vi.mock('@/components/notifications/NotificationPreferences', () => ({
NotificationPreferences: () => (
Expand Down Expand Up @@ -52,7 +47,7 @@ describe('SettingsPage', () => {
});

it('should render header and footer', () => {
render(<SettingsContent user={null} />);
render(<SettingsContent user={null} footer={<footer data-testid="footer">Footer</footer>} />);

expect(screen.getByTestId('header')).toBeInTheDocument();
expect(screen.getByTestId('footer')).toBeInTheDocument();
Expand Down
3 changes: 2 additions & 1 deletion apps/web/src/app/settings/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Metadata } from 'next';
import { createClient } from '@/lib/supabase/server';
import type { UserData } from '@/components/header';
import { Footer } from '@/components/footer';
import { SettingsContent } from './settings-content';

export const metadata: Metadata = {
Expand Down Expand Up @@ -33,5 +34,5 @@ export default async function SettingsPage() {
// Supabase not configured — user stays null
}

return <SettingsContent user={user} />;
return <SettingsContent user={user} footer={<Footer />} />;
}
11 changes: 8 additions & 3 deletions apps/web/src/app/settings/settings-content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { useState, useEffect } from 'react';
import Link from 'next/link';
import { User, Video, Users, Palette, Info, ArrowLeft, Check, Bell } from 'lucide-react';
import { HeaderClient } from '@/components/header-client';
import { Footer } from '@/components/footer';
import { NotificationPreferences } from '@/components/notifications/NotificationPreferences';
import { YouTubeConnect } from './youtube-connect';
import type { UserData } from '@/components/header';
Expand Down Expand Up @@ -49,7 +48,13 @@ const DEFAULT_SETTINGS: AppSettings = {
// Local storage key for settings
const SETTINGS_KEY = 'pairux-web-settings';

export function SettingsContent({ user }: { user: UserData | null }) {
export function SettingsContent({
user,
footer,
}: {
user: UserData | null;
footer?: React.ReactNode;
}) {
const [settings, setSettings] = useState<AppSettings>(DEFAULT_SETTINGS);
const [saved, setSaved] = useState(false);

Expand Down Expand Up @@ -457,7 +462,7 @@ export function SettingsContent({ user }: { user: UserData | null }) {
</div>
</main>

<Footer />
{footer}
</div>
);
}
48 changes: 4 additions & 44 deletions apps/web/src/components/footer.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Link from 'next/link';
import { Footer as PfsFooter } from '@profullstack/footer/react';
import { Logo } from '@/components/Logo';

// Custom GitHub icon SVG component (brand icons deprecated in lucide)
Expand Down Expand Up @@ -193,50 +194,9 @@ export function Footer() {
</div>
</div>

{/* Bottom bar */}
<div className="mt-12 border-t border-gray-200 pt-8">
<p className="text-center text-sm text-gray-500">
&copy; {new Date().getFullYear()}{' '}
<a
href="https://profullstack.com"
target="_blank"
rel="noopener noreferrer"
className="hover:text-gray-700"
>
Profullstack, Inc.
</a>{' '}
Open source under MIT License.
</p>
<nav
className="webring mt-3 flex justify-center gap-3 text-sm text-gray-500"
aria-label="Profullstack webring"
>
<a
href="https://rssamplifier.com/ring/profullstack/previous?from=https%3A%2F%2Fpairux.com%2F"
rel="prev"
className="hover:text-gray-700"
>
{'<<'}
</a>
<a href="https://rssamplifier.com/ring/profullstack" className="hover:text-gray-700">
Profullstack
</a>
<a
href="https://rssamplifier.com/ring/profullstack/next?from=https%3A%2F%2Fpairux.com%2F"
rel="next"
className="hover:text-gray-700"
>
{'>>'}
</a>
<a
href="https://rssamplifier.com/ring/profullstack/random?from=https%3A%2F%2Fpairux.com%2F"
title="Random site"
aria-label="Random site"
className="hover:text-gray-700"
>
{'⚄'}
</a>
</nav>
{/* Bottom bar: copyright + Profullstack ring, from @profullstack/footer */}
<div className="mt-12">
<PfsFooter site="https://pairux.com/" tagline="Open source under MIT License." />
</div>
</div>
</footer>
Expand Down
17 changes: 17 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading