Skip to content

Commit

Permalink
feat: landing page (#23)
Browse files Browse the repository at this point in the history
> 首页内容添加 + 样式优化
* 🧶 添加站点介绍、使用说明、安装帮助、registry 实时状态等内容
* 🧶 添加 cnpmweb、cnpmcore 开源地址链接
* 💄 添加统一导航,首页部分也一并添加
  • Loading branch information
elrrrrrrr authored Aug 18, 2023
1 parent aff9c42 commit 4f464ae
Show file tree
Hide file tree
Showing 9 changed files with 184 additions and 32 deletions.
18 changes: 15 additions & 3 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { GithubOutlined } from "@ant-design/icons";
import { Segmented } from "antd";
import { Dropdown, Segmented } from "antd";
import { createStyles, cx } from "antd-style";
import Link from "next/link";

Expand Down Expand Up @@ -37,7 +37,10 @@ export default function Header({title, themeMode, setThemeMode}: any) {
<span style={{ marginRight: 16 }}>
<Segmented
value={themeMode}
options={[{label: '🌞', value: 'light'}, {label: '🌛', value: 'dark'}]}
options={[
{ label: '🌞', value: 'light' },
{ label: '🌛', value: 'dark' },
]}
onChange={(v) => {
setThemeMode(v as 'dark' | 'light');
}}
Expand All @@ -49,7 +52,16 @@ export default function Header({title, themeMode, setThemeMode}: any) {
target='_blank'
style={{ color: 'inherit' }}
>
<GithubOutlined />
<Dropdown
menu={{
items: [
{ key: 'cnpmweb', label: <Link target="_blank" href={"https://github.com/cnpm/cnpmweb"}>🪞 cnpmweb</Link> },
{ key: 'cnpmcore', label: <Link target="_blank" href={"https://github.com/cnpm/cnpmcore"}>📦 cnpmcore</Link> },
],
}}
>
<GithubOutlined />
</Dropdown>
</Link>
</span>
</nav>
Expand Down
107 changes: 107 additions & 0 deletions src/components/Introduce.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
'use client';
import React from 'react';
import { Divider, Tooltip, Typography } from 'antd';
import useRegistry from '@/hooks/useRegistry';
const { Title, Paragraph, Text, Link } = Typography;

export default function Introduce() {
const { data } = useRegistry();
return (
<Typography style={{ textAlign: 'left', marginTop: '32px' }}>
<Title level={2}>站点介绍</Title>
<Paragraph>
<blockquote>
这是一个完整
<Link target={'_blank'} href='https://www.npmjs.com'>
npmjs.org
</Link>{' '}
镜像,你可以用此代替官方版本(只读),我们将尽量与官方服务
<Text strong>实时同步</Text>
<br/>
我们的前后端应用代码均已开源,前端应用为{' '}
<Link target='_blank' href='https://github.com/cnpm/cnpmweb'>
cnpmweb
</Link>
,服务端应用为{' '}
<Link target='_blank' href='https://github.com/cnpm/cnpmcore'>
cnpmcore
</Link>{' '}
欢迎共建。
</blockquote>
目前我们已累积同步了 <Text strong>{data?.doc_count || '-'}</Text>{' '}
个包,近7日下载量为 <Text strong>{data?.download.thisweek || '-'}</Text>
<Divider />
<ul>
<li>
最近更新的包为
<Link
href={`/${data?.sync_changes_steam.last_package}`}
style={{ marginLeft: 8 }}
disabled={!data}
>
{data?.sync_changes_steam.last_package || '-'}
</Link>
</li>
<li>
最近同步的时间为
<Tooltip title={'由于近期功能升级,同步预计与8月26日凌晨恢复'}>
<Text strong style={{ paddingLeft: 8 }}>
{data?.sync_changes_steam.last_package_created || '-'}
</Text>
</Tooltip>
</li>
</ul>
</Paragraph>

<Title level={2}>使用说明</Title>
<Paragraph>
你可以使用我们定制的 <Link href='/cnpm'>cnpm</Link> 命令行工具代替默认的
npm。
<br />
cnpm 支持了写相关操作外的所有命令,例如 install、info、view 等。
<br />
<pre>
$ npm install -g cnpm --registry=https://registry.npmmirror.com
</pre>
或者你直接通过添加 npm 参数 alias 一个新命令:
<pre>
alias cnpm=&quot;npm --registry=https://registry.npmmirror.com \
--cache=$HOME/.npm/.cache/cnpm \
--disturl=https://npmmirror.com/mirrors/node \
--userconfig=$HOME/.cnpmrc&quot;
</pre>
当然,你也可以使用任意你心仪的命令行工具,只要配置 registry 即可
<pre>$ npm config set registry https://registry.npmmirror.com</pre>
</Paragraph>

<Title level={3}>安装模块</Title>
<Paragraph>
<pre>$ cnpm install [name]</pre>
</Paragraph>
<Title level={3}>同步模块</Title>
<Paragraph>
<pre>$ cnpm sync cnpmcore</pre>
当然, 你可以直接通过 web 方式来同步, 界面打开时会自动比对版本信息
<pre>$ open https://npmmirror.com/sync/cnpmcore</pre>
</Paragraph>

<Paragraph>
<ul>
<li>
<Link href='https://registry.npmmiorror.com' target='_blank'>
registry 站点
</Link>
</li>
<li>
<Link href='/'>web 站点</Link>
</li>
<li>
<Link href='/mirrors'>二进制文件镜像</Link>
</li>
</ul>
</Paragraph>
<Divider />
</Typography>
);
}
4 changes: 2 additions & 2 deletions src/components/LandingSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export default function LandingSearch() {
label: (
<>
<Typography.Text>
{hit.name}@{hit.version}
{hit.name}
</Typography.Text>
<br />
<Typography.Text type='secondary'>
Expand Down Expand Up @@ -62,7 +62,7 @@ export default function LandingSearch() {
>
<Input.Search
size='large'
placeholder='搜索服务由 Algolia 提供...'
placeholder='输入 NPM 包名、作者、关键字等信息即可搜索,服务由 Algolia 提供...'
enterButton
loading={!!(search && isLoading)}
/>
Expand Down
11 changes: 11 additions & 0 deletions src/hooks/useRegistry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import useSwr from 'swr';

const REGISTRY = 'https://registry.npmmirror.com';


export default function useRegistry() {
return useSwr('registry', async () => {
return fetch(`${REGISTRY}`)
.then((res) => res.json());
});
}
24 changes: 24 additions & 0 deletions src/hooks/useTheme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { ThemeMode } from "antd-style";
import { useEffect, useState } from "react";

const LOCAL_STORAGE_THEME = 'themeMode';

export function useTheme() {
const [themeMode, setThemeMode] = useState<ThemeMode>('light');
useEffect(() => {
const themeMode = localStorage.getItem(LOCAL_STORAGE_THEME) as ThemeMode;
if (themeMode) {
setThemeMode(themeMode);
}
}, []);
useEffect(() => {
document
.querySelector('html')
?.setAttribute('style', `color-scheme: ${themeMode};`);
}, [themeMode]);

return [themeMode, (v: ThemeMode) => {
localStorage.setItem(LOCAL_STORAGE_THEME, v);
setThemeMode(v);
}];
}
2 changes: 1 addition & 1 deletion src/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default async function middleware(req: NextRequest) {
const pathGroups = pathname.split("/").filter(Boolean);

// logo
if (pathname === '/cnpm.png') {
if (['/cnpm.png', '/favicon.ico'].includes(pathname)) {
return NextResponse.next();
}

Expand Down
20 changes: 17 additions & 3 deletions src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,35 @@ import LandingSearch from '@/components/LandingSearch';
import AdBanner from '@/components/AdBanner';
import AdVPS from '@/components/AdVPS';
import Footer from '@/components/Footer';
import Introduce from '@/components/Introduce';
import { ThemeMode, ThemeProvider as _ThemeProvider } from 'antd-style';
import Header from '@/components/Header';
import { useTheme } from '@/hooks/useTheme';

const ThemeProvider = _ThemeProvider as any;

export default function Home() {

const [themeMode, setThemeMode] = useTheme();

return (
<>
<ThemeProvider themeMode={themeMode as ThemeMode}>
<Header
themeMode={themeMode}
setThemeMode={setThemeMode}
/>
<main className={styles.main}>
<AdBanner />
<div className={styles.search}>
<h1>npmmirror 镜像站</h1>
<h1 style={{ fontSize: 48, marginTop: 48 }}>npmmirror 镜像站</h1>
<LandingSearch />
<Introduce />
</div>
<div style={{ marginTop: '5rem' }}>
<AdVPS />
</div>
</main>
<Footer />
</>
</ThemeProvider>
);
}
25 changes: 4 additions & 21 deletions src/pages/package/[...slug]/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,13 @@ import CustomTabs from '@/components/CustomTabs';
import { PackageManifest, useInfo } from '@/hooks/useManifest';
import Footer from '@/components/Footer';
import { useRouter } from 'next/router';
import { useEffect, useMemo, useState } from 'react';
import { useMemo } from 'react';
import { Result, Spin } from 'antd';
import Header from '@/components/Header';
import { useTheme } from '@/hooks/useTheme';

const ThemeProvider = _ThemeProvider as any;

const LOCAL_STORAGE_THEME = 'themeMode';

export type PageProps = {
manifest: PackageManifest;
version?: string;
Expand Down Expand Up @@ -56,20 +55,7 @@ export default function PackagePage({
}) {
const router = useRouter();

const [themeMode, setThemeMode] = useState<ThemeMode>('light');

useEffect(() => {
const themeMode = localStorage.getItem(LOCAL_STORAGE_THEME) as ThemeMode;
if (themeMode) {
setThemeMode(themeMode);
}
}, []);

useEffect(() => {
document
.querySelector('html')
?.setAttribute('style', `color-scheme: ${themeMode};`);
}, [themeMode]);
const [themeMode, setThemeMode] = useTheme();

const pkgName = useMemo(() => {
const { slug } = router.query;
Expand Down Expand Up @@ -125,10 +111,7 @@ export default function PackagePage({
<Header
title={`${resData.name}@${version}`}
themeMode={themeMode}
setThemeMode={(v: ThemeMode) => {
localStorage.setItem(LOCAL_STORAGE_THEME, v);
setThemeMode(v);
}}
setThemeMode={setThemeMode}
/>
<section style={{ paddingLeft: 16 }}>
<CustomTabs activateKey={type} pkg={resData}></CustomTabs>
Expand Down
5 changes: 3 additions & 2 deletions src/pages/page.module.css
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
.search {
width: 40rem;
width: 760px;
text-align: center;
margin: 0 auto;
margin-top: 15rem;
margin-top: 16px;
}

.main {
min-height: calc(100vh - 32px);
margin-bottom: 32px;
}

0 comments on commit 4f464ae

Please sign in to comment.