Skip to content

Commit f5f14a7

Browse files
ralyodioclaude
andauthored
feat(footer): use @profullstack/footer (#303)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 28f5c4e commit f5f14a7

5 files changed

Lines changed: 15 additions & 19 deletions

File tree

‎bun.lock‎

Lines changed: 3 additions & 0 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 & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
"@noble/hashes": "^2.0.0",
6262
"@profullstack/autoblog": "github:profullstack/autoblog#75e54af77cbcf61dbd90fb3ed529c1b2dad1ed6f",
6363
"@profullstack/encrypt": "^0.1.0",
64+
"@profullstack/footer": "latest",
6465
"@profullstack/openprofile": "^0.2.0",
6566
"@profullstack/pairux-embed": "^0.1.0",
6667
"@profullstack/stack": "^0.1.3",

‎src/app/client-layout.jsx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import ActiveCallInterface from '@/lib/components/voice-call/ActiveCallInterface
1717
// token, since passkey/CoinPay/phone sessions have no cookie.
1818
installApiAuth({ refresh: (token) => useAuthStore.getState().refreshSession(token) });
1919

20-
export default function ClientLayout({ children }) {
20+
export default function ClientLayout({ children, footerBottom }) {
2121
const pathname = usePathname();
2222
const currentTheme = useThemeStore((s) => s.currentTheme);
2323
const { t: _t } = useI18n();
@@ -60,7 +60,7 @@ export default function ClientLayout({ children }) {
6060
<div className="app" suppressHydrationWarning>
6161
<Navbar />
6262
<main className="main-content">{children}</main>
63-
{shouldShowFooter && <Footer />}
63+
{shouldShowFooter && <Footer bottom={footerBottom} />}
6464
{mounted && (
6565
<>
6666
<PWAToastManager />

‎src/app/layout.jsx‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
import './globals.css';
22
import ClientLayout from './client-layout.jsx';
33
import Script from "next/script";
4+
import { Footer as PfsFooter } from '@profullstack/footer/react';
45

56
const SITE_URL = (process.env.NEXT_PUBLIC_APP_URL ?? process.env.NEXT_PUBLIC_BASE_URL ?? 'https://qrypt.chat').replace(/\/$/, '');
67

8+
// Re-render hourly so @profullstack/footer picks up its @latest template.
9+
export const revalidate = 3600;
10+
711
export const metadata = {
812
metadataBase: new URL(SITE_URL),
913
title: {
@@ -142,7 +146,7 @@ export default function RootLayout({ children }) {
142146
/>
143147
</head>
144148
<body suppressHydrationWarning>
145-
<ClientLayout>{children}</ClientLayout>
149+
<ClientLayout footerBottom={<PfsFooter site="https://qrypt.chat/" />}>{children}</ClientLayout>
146150
<Script data-site="38c4083a-a35e-435d-8a0e-3510c465f419" src="https://crawlproof.com/stats.js" strategy="afterInteractive" />
147151
</body>
148152
</html>

‎src/lib/components/Footer.jsx‎

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,8 @@ const socialLinks = [
99
{ name: 'Bluesky', url: 'https://bsky.app/profile/chovyfu.bsky.social' },
1010
];
1111

12-
const currentYear = new Date().getFullYear();
1312

14-
export default function Footer() {
13+
export default function Footer({ bottom }) {
1514
const { t } = useI18n();
1615
const onionUrl = process.env.NEXT_PUBLIC_ONION_URL;
1716
const isOnionSite = typeof window !== 'undefined' && window.location.hostname.endsWith('.onion');
@@ -73,15 +72,8 @@ export default function Footer() {
7372
</div>
7473
</div>
7574

76-
<div className="footer-bottom">
77-
<p>© {currentYear} QryptChat. All rights reserved.</p>
78-
<nav className="webring" aria-label="Profullstack webring">
79-
<a href="https://rssamplifier.com/ring/profullstack/previous?from=https%3A%2F%2Fqrypt.chat%2F" rel="prev">{"<<"}</a>
80-
<a href="https://rssamplifier.com/ring/profullstack">Profullstack</a>
81-
<a href="https://rssamplifier.com/ring/profullstack/next?from=https%3A%2F%2Fqrypt.chat%2F" rel="next">{">>"}</a>
82-
<a href="https://rssamplifier.com/ring/profullstack/random?from=https%3A%2F%2Fqrypt.chat%2F" title="Random site" aria-label="Random site">{"⚄"}</a>
83-
</nav>
84-
</div>
75+
{/* Copyright + Profullstack webring: @profullstack/footer, server-rendered in app/layout.jsx */}
76+
{bottom && <div className="footer-bottom">{bottom}</div>}
8577

8678
<style>{`
8779
.footer { background: var(--color-bg-secondary); border-top: 1px solid var(--color-border-primary); padding: var(--space-12) 0 var(--space-6); }
@@ -100,11 +92,7 @@ export default function Footer() {
10092
.social-links { display: flex; flex-direction: column; gap: var(--space-2); }
10193
.social-link { color: var(--color-text-secondary); text-decoration: none; font-size: 0.875rem; transition: color .2s; }
10294
.social-link:hover { color: var(--color-brand-primary); }
103-
.footer-bottom { max-width: 1200px; margin: var(--space-8) auto 0; padding: var(--space-6) var(--space-6) 0; border-top: 1px solid var(--color-border-primary); }
104-
.footer-bottom p { color: var(--color-text-secondary); font-size: 0.875rem; }
105-
.footer-bottom .webring { display: flex; gap: var(--space-3); margin-top: var(--space-2); font-size: 0.75rem; }
106-
.footer-bottom .webring a { color: var(--color-text-secondary); text-decoration: none; transition: color .2s; }
107-
.footer-bottom .webring a:hover { color: var(--color-brand-primary); }
95+
.footer-bottom { max-width: 1200px; margin: var(--space-8) auto 0; }
10896
@media (max-width: 768px) {
10997
.footer-content { grid-template-columns: 1fr; }
11098
.footer-links { flex-direction: column; }

0 commit comments

Comments
 (0)