Skip to content

Commit e10b0b1

Browse files
committed
feat: customize Open Library layout and styling
1 parent 07745ad commit e10b0b1

5 files changed

Lines changed: 352 additions & 103 deletions

File tree

components/open-library/Footer.tsx

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,29 @@
11
import React from 'react';
2-
import { Container, Row, Col, Nav } from 'react-bootstrap';
2+
import { Row, Col, Nav } from 'react-bootstrap';
3+
4+
//
5+
const ContentContainer: React.FC<{ children: React.ReactNode }> = ({
6+
children,
7+
}) => {
8+
return (
9+
<div
10+
style={{
11+
maxWidth: '1200px',
12+
margin: '0 auto',
13+
padding: '0 20px',
14+
width: '100%',
15+
boxSizing: 'border-box',
16+
}}
17+
>
18+
{children}
19+
</div>
20+
);
21+
};
322

423
const FooterComponent = () => {
524
return (
625
<footer className="bg-dark text-light py-4 mt-5">
7-
<Container>
26+
<ContentContainer>
827
<Row>
928
<Col md={4} className="mb-3 mb-md-0">
1029
<h5>Open Library</h5>
@@ -61,7 +80,7 @@ const FooterComponent = () => {
6180
</small>
6281
</Col>
6382
</Row>
64-
</Container>
83+
</ContentContainer>
6584
</footer>
6685
);
6786
};

components/open-library/Layout.tsx

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import React from 'react';
2+
import Head from 'next/head';
3+
import NavbarComponent from './Navbar';
4+
import FooterComponent from './Footer';
5+
6+
// 内容容器组件,使内容居中但不添加边框
7+
const ContentContainer: React.FC<{ children: React.ReactNode }> = ({
8+
children,
9+
}) => {
10+
return (
11+
<div
12+
style={{
13+
maxWidth: '1200px',
14+
margin: '0 auto',
15+
padding: '0 20px',
16+
width: '100%',
17+
boxSizing: 'border-box',
18+
}}
19+
>
20+
{children}
21+
</div>
22+
);
23+
};
24+
25+
interface LayoutProps {
26+
children: React.ReactNode;
27+
title?: string;
28+
}
29+
30+
/**
31+
* Open Library 的共享布局组件
32+
* 包含导航栏、页脚和内容容器
33+
* 所有 Open Library 页面都应使用此布局
34+
*/
35+
const Layout: React.FC<LayoutProps> = ({
36+
children,
37+
title = 'Open Library - Open Source Bazaar',
38+
}) => {
39+
return (
40+
<>
41+
<Head>
42+
<title>{title}</title>
43+
<meta name="viewport" content="width=device-width, initial-scale=1" />
44+
</Head>
45+
46+
{/* 导航栏 */}
47+
<NavbarComponent />
48+
49+
{/* 主要内容 */}
50+
<main>{children}</main>
51+
52+
{/* 页脚 */}
53+
<FooterComponent />
54+
</>
55+
);
56+
};
57+
58+
// 导出布局组件和内容容器组件,以便在页面中使用
59+
export { Layout, ContentContainer };
60+
export default Layout;

components/open-library/Navbar.tsx

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,37 @@ import {
1111
const NavbarComponent = () => {
1212
return (
1313
<Navbar bg="light" expand="lg" sticky="top" className="mb-4 shadow-sm">
14-
<Container fluid>
15-
<Navbar.Brand href="#home" className="d-flex align-items-center">
14+
{/* 使用自定义的居中容器替代 Container fluid,与页面内容保持一致的宽度和居中效果 */}
15+
<div
16+
style={{
17+
maxWidth: '1200px',
18+
margin: '0 auto',
19+
padding: '0 20px',
20+
width: '100%',
21+
boxSizing: 'border-box',
22+
display: 'flex',
23+
flexWrap: 'wrap',
24+
alignItems: 'center',
25+
justifyContent: 'space-between',
26+
}}
27+
>
28+
<Navbar.Brand
29+
href="/open-library"
30+
className="d-flex align-items-center"
31+
>
1632
Open Library
1733
</Navbar.Brand>
1834
<Navbar.Toggle aria-controls="basic-navbar-nav" />
1935
<Navbar.Collapse id="basic-navbar-nav">
2036
<Nav className="me-auto">
21-
<Nav.Link href="#home">Home</Nav.Link>
22-
<Nav.Link href="#catalog">Catalog</Nav.Link>
23-
<Nav.Link href="#about">About</Nav.Link>
24-
<Nav.Link href="#donate">Donate</Nav.Link>
25-
<Nav.Link href="#how-to-borrow">How to Borrow</Nav.Link>
26-
<Nav.Link href="#review">Review</Nav.Link>
37+
<Nav.Link href="/open-library">Home</Nav.Link>
38+
<Nav.Link href="/open-library/books">Catalog</Nav.Link>
39+
<Nav.Link href="/open-library/about">About</Nav.Link>
40+
<Nav.Link href="/open-library/donate">Donate</Nav.Link>
41+
<Nav.Link href="/open-library/how-to-borrow">
42+
How to Borrow
43+
</Nav.Link>
44+
<Nav.Link href="/open-library/review">Review</Nav.Link>
2745
</Nav>
2846
<Form className="d-flex">
2947
<FormControl
@@ -38,7 +56,7 @@ const NavbarComponent = () => {
3856
Login/Register
3957
</Button>
4058
</Navbar.Collapse>
41-
</Container>
59+
</div>
4260
</Navbar>
4361
);
4462
};

pages/_app.tsx

Lines changed: 71 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ const App: FC<AppProps> = observer(({ Component, pageProps }) => {
3535
const { pathname } = useRouter();
3636
const thisFullYear = new Date().getFullYear();
3737

38+
// 检查是否是 Open Library 路径
39+
const isOpenLibraryPath = pathname.startsWith('/open-library');
40+
3841
const topNavBarMenu = [
3942
{ href: '/about', name: t('about') },
4043
{ href: '/history', name: t('history') },
@@ -59,62 +62,75 @@ const App: FC<AppProps> = observer(({ Component, pageProps }) => {
5962
<link rel="icon" href="/favicon.ico" />
6063
</Head>
6164

62-
<Navbar bg="dark" variant="dark" fixed="top" expand="lg">
63-
<Container>
64-
<Navbar.Brand href="/" className="fw-bolder">
65-
{t('open_source_bazaar')}
66-
</Navbar.Brand>
67-
<Navbar.Toggle aria-controls="navbarScroll" />
68-
<Navbar.Collapse id="navbarScroll">
69-
<Nav className="me-auto my-2 my-lg-0" navbarScroll>
70-
{topNavBarMenu.map(({ href, name }) => (
71-
<Nav.Link
72-
key={`${href}-${name}`}
73-
href={href}
74-
className={
75-
pathname === `${href}` ? 'fw-bolder text-light' : ''
76-
}
77-
>
78-
{name}
79-
</Nav.Link>
80-
))}
81-
</Nav>
82-
83-
<LanguageMenu />
84-
</Navbar.Collapse>
85-
</Container>
86-
</Navbar>
87-
88-
<div className="mt-5 pt-2">
89-
<PageContent>
90-
<Component {...pageProps} />
91-
</PageContent>
92-
</div>
93-
94-
<footer className="mw-100 bg-dark text-white">
95-
<p className="text-center my-0 py-3">
96-
<span className="pr-3">
97-
© 2021{thisFullYear === 2021 ? '' : `-${thisFullYear}`}{' '}
98-
{t('open_source_bazaar')}
99-
</span>
100-
{/* <a
101-
className="flex-fill d-flex justify-content-center align-items-center"
102-
href="https://vercel.com/"
103-
target="_blank"
104-
rel="noopener noreferrer"
105-
>
106-
Powered by
107-
<span className="mx-2">
108-
<Image
109-
src="/vercel.svg"
110-
alt="Vercel Logo"
111-
width={72}
112-
height={16}
113-
/>
65+
{/* 只在非 Open Library 路径显示主站导航栏 */}
66+
{!isOpenLibraryPath && (
67+
<Navbar bg="dark" variant="dark" fixed="top" expand="lg">
68+
<Container>
69+
<Navbar.Brand href="/" className="fw-bolder">
70+
{t('open_source_bazaar')}
71+
</Navbar.Brand>
72+
<Navbar.Toggle aria-controls="navbarScroll" />
73+
<Navbar.Collapse id="navbarScroll">
74+
<Nav className="me-auto my-2 my-lg-0" navbarScroll>
75+
{topNavBarMenu.map(({ href, name }) => (
76+
<Nav.Link
77+
key={`${href}-${name}`}
78+
href={href}
79+
className={
80+
pathname === `${href}` ? 'fw-bolder text-light' : ''
81+
}
82+
>
83+
{name}
84+
</Nav.Link>
85+
))}
86+
</Nav>
87+
88+
<LanguageMenu />
89+
</Navbar.Collapse>
90+
</Container>
91+
</Navbar>
92+
)}
93+
94+
{/* 根据路径决定是否使用 PageContent 包装 */}
95+
{isOpenLibraryPath ? (
96+
// Open Library 路径直接渲染内容,不使用 PageContent
97+
<Component {...pageProps} />
98+
) : (
99+
// 其他路径使用原来的 PageContent 包装
100+
<div className="mt-5 pt-2">
101+
<PageContent>
102+
<Component {...pageProps} />
103+
</PageContent>
104+
</div>
105+
)}
106+
107+
{/* 只在非 Open Library 路径显示主站页脚 */}
108+
{!isOpenLibraryPath && (
109+
<footer className="mw-100 bg-dark text-white">
110+
<p className="text-center my-0 py-3">
111+
<span className="pr-3">
112+
2021{thisFullYear === 2021 ? '' : `-${thisFullYear}`}{' '}
113+
{t('open_source_bazaar')}
114114
</span>
115-
</a> */}
116-
</p>
117-
</footer>
115+
{/* <a
116+
className="flex-fill d-flex justify-content-center align-items-center"
117+
href="https://vercel.com/"
118+
target="_blank"
119+
rel="noopener noreferrer"
120+
>
121+
Powered by
122+
<span className="mx-2">
123+
<Image
124+
src="/vercel.svg"
125+
alt="Vercel Logo"
126+
width={72}
127+
height={16}
128+
/>
129+
</span>
130+
</a> */}
131+
</p>
132+
</footer>
133+
)}
118134
</>
119135
);
120136
});

0 commit comments

Comments
 (0)