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
2 changes: 2 additions & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
public-hoist-pattern[] = *import-in-the-middle*
public-hoist-pattern[] = *require-in-the-middle*
auto-install-peers = false
80 changes: 41 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
- Component suite: [Bootstrap v5][4]
- PWA framework: [Workbox v6][5]
- State management: [MobX v6][11]
- CI / CD: GitHub [Actions][12] + [Vercel][13]
- Monitor service: [Sentry][14]
- API router: [Koa 2][12]
- CI / CD: GitHub [Actions][13] + [Vercel][14]
- Monitor service: [Sentry][15]

## Major examples

Expand All @@ -31,20 +32,20 @@

1. Install GitHub apps in your organization or account:

1. [Probot settings][15]: set up Issue labels & Pull Request rules
2. [PR badge][16]: set up Online [VS Code][17] editor entries in Pull Request description
1. [Probot settings][16]: set up Issue labels & Pull Request rules
2. [PR badge][17]: set up Online [VS Code][18] editor entries in Pull Request description

2. Click the **[<kbd>Use this template</kbd>][18] button** on the top of this GitHub repository's home page, then create your own repository in the app-installed namespace above
2. Click the **[<kbd>Use this template</kbd>][19] button** on the top of this GitHub repository's home page, then create your own repository in the app-installed namespace above

3. Click the **[<kbd>Open in GitHub codespaces</kbd>][8] button** on the top of ReadMe file, then an **online VS Code development environment** will be started immediately

4. Set [Vercel variables][19] as [Repository secrets][20], then every commit will get an independent **Preview URL**
4. Set [Vercel variables][20] as [Repository secrets][21], then every commit will get an independent **Preview URL**

5. Recommend to add a [Notification step in GitHub actions][21] for your Team IM app
5. Recommend to add a [Notification step in GitHub actions][22] for your Team IM app

6. Remind the PMs & users of your product to submit **Feature/Enhancement** requests or **Bug** reports with [Issue forms][22] instead of IM messages or Mobile Phone calls
6. Remind the PMs & users of your product to submit **Feature/Enhancement** requests or **Bug** reports with [Issue forms][23] instead of IM messages or Mobile Phone calls

7. Collect all these issues into [Project kanbans][23], then create **Pull requests** & add `closes #issue_number` into its description for automation
7. Collect all these issues into [Project kanbans][24], then create **Pull requests** & add `closes #issue_number` into its description for automation

## Getting Started

Expand All @@ -59,35 +60,35 @@ Open http://localhost:3000 with your browser to see the result.

You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file.

[API routes][24] can be accessed on http://localhost:3000/api/hello. This endpoint can be edited in `pages/api/hello.ts`.
[API routes][25] can be accessed on http://localhost:3000/api/hello. This endpoint can be edited in `pages/api/hello.ts`.

The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as API routes instead of React pages.

## Learn More

To learn more about Next.js, take a look at the following resources:

- [Next.js Documentation][25] - learn about Next.js features and API.
- [Learn Next.js][26] - an interactive Next.js tutorial.
- [Next.js Documentation][26] - learn about Next.js features and API.
- [Learn Next.js][27] - an interactive Next.js tutorial.

You can check out [the Next.js GitHub repository][27] - your feedback and contributions are welcome!
You can check out [the Next.js GitHub repository][28] - your feedback and contributions are welcome!

## Deployment

### Environment variables

| name | file | description |
| :----------------------: | :----------: | :---------------------: |
| `SENTRY_AUTH_TOKEN` | `.env.local` | [Official document][28] |
| `SENTRY_ORG` | `.env` | [Official document][29] |
| `SENTRY_PROJECT` | `.env` | [Official document][29] |
| `NEXT_PUBLIC_SENTRY_DSN` | `.env` | [Official document][30] |
| `SENTRY_AUTH_TOKEN` | `.env.local` | [Official document][29] |
| `SENTRY_ORG` | `.env` | [Official document][30] |
| `SENTRY_PROJECT` | `.env` | [Official document][30] |
| `NEXT_PUBLIC_SENTRY_DSN` | `.env` | [Official document][31] |

### Vercel

The easiest way to deploy your Next.js app is to use the [Vercel Platform][13] from the creators of Next.js.
The easiest way to deploy your Next.js app is to use the [Vercel Platform][14] from the creators of Next.js.

Check out our [Next.js deployment documentation][31] for more details.
Check out our [Next.js deployment documentation][32] for more details.

### Docker

Expand All @@ -107,23 +108,24 @@ pnpm container
[9]: https://gitpod.io/?autostart=true#https://github.com/idea2app/Next-Bootstrap-ts
[10]: https://mdxjs.com/
[11]: https://mobx.js.org/
[12]: https://github.com/features/actions
[13]: https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme
[14]: https://sentry.io/
[15]: https://github.com/apps/settings
[16]: https://pullrequestbadge.com/
[17]: https://code.visualstudio.com/
[18]: https://github.com/new?template_name=Next-Bootstrap-ts&template_owner=idea2app
[19]: https://github.com/idea2app/Next-Bootstrap-ts/blob/80967ed49045af9dbcf4d3695a2c39d53a6f71f1/.github/workflows/pull-request.yml#L9-L11
[20]: https://github.com/idea2app/Next-Bootstrap-ts/settings/secrets/actions
[21]: https://github.com/kaiyuanshe/kaiyuanshe.github.io/blob/bb4675a56bf1d6b207231313da5ed0af7cf0ebd6/.github/workflows/pull-request.yml#L32-L56
[22]: https://github.com/idea2app/Next-Bootstrap-ts/issues/new/choose
[23]: https://github.com/idea2app/Next-Bootstrap-ts/projects
[24]: https://nextjs.org/docs/api-routes/introduction
[25]: https://nextjs.org/docs
[26]: https://nextjs.org/learn
[27]: https://github.com/vercel/next.js/
[28]: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#use-configuration-files-for-source-map-upload
[29]: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#use-environment-variables
[30]: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#create-initialization-config-files
[31]: https://nextjs.org/docs/deployment
[12]: https://koajs.com/
[13]: https://github.com/features/actions
[14]: https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme
[15]: https://sentry.io/
[16]: https://github.com/apps/settings
[17]: https://pullrequestbadge.com/
[18]: https://code.visualstudio.com/
[19]: https://github.com/new?template_name=Next-Bootstrap-ts&template_owner=idea2app
[20]: https://github.com/idea2app/Next-Bootstrap-ts/blob/80967ed49045af9dbcf4d3695a2c39d53a6f71f1/.github/workflows/pull-request.yml#L9-L11
[21]: https://github.com/idea2app/Next-Bootstrap-ts/settings/secrets/actions
[22]: https://github.com/FreeCodeCamp-Chengdu/FreeCodeCamp-Chengdu.github.io/blob/8df9944449002758f7ec809deeb260ce08182259/.github/workflows/main.yml#L34-L63
[23]: https://github.com/idea2app/Next-Bootstrap-ts/issues/new/choose
[24]: https://github.com/idea2app/Next-Bootstrap-ts/projects
[25]: https://nextjs.org/docs/api-routes/introduction
[26]: https://nextjs.org/docs
[27]: https://nextjs.org/learn
[28]: https://github.com/vercel/next.js/
[29]: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#use-configuration-files-for-source-map-upload
[30]: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#use-environment-variables
[31]: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#create-initialization-config-files
[32]: https://nextjs.org/docs/deployment
88 changes: 46 additions & 42 deletions components/Git/Card.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { text2color } from 'idea-react';
import { GitRepository } from 'mobx-github';
import { observer } from 'mobx-react';
import { FC } from 'react';
import { FC, useContext } from 'react';
import { Badge, Button, Card, CardProps, Col, Row } from 'react-bootstrap';

import { t } from '../../models/Translation';
import { I18nContext } from '../../models/Translation';
import { GitLogo } from './Logo';

export interface GitCardProps
Expand All @@ -24,45 +24,49 @@ export const GitCard: FC<GitCardProps> = observer(
description,
homepage,
...props
}) => (
<Card className={className} {...props}>
<Card.Body className="d-flex flex-column gap-3">
<Card.Title as="h3" className="h5">
<a target="_blank" href={html_url} rel="noreferrer">
{full_name}
</a>
</Card.Title>
}) => {
const { t } = useContext(I18nContext);

<nav className="flex-fill">
{topics.map(topic => (
<Badge
key={topic}
className="me-1 text-decoration-none"
bg={text2color(topic, ['light'])}
as="a"
target="_blank"
href={`https://github.com/topics/${topic}`}
>
{topic}
</Badge>
))}
</nav>
<Row as="ul" className="list-unstyled g-4" xs={4}>
{languages.map(language => (
<Col key={language} as="li">
<GitLogo name={language} />
</Col>
))}
</Row>
<Card.Text>{description}</Card.Text>
</Card.Body>
<Card.Footer className="d-flex justify-content-between align-items-center">
{homepage && (
<Button variant="success" target="_blank" href={homepage}>
{t('home_page')}
</Button>
)}
</Card.Footer>
</Card>
),
return (
<Card className={className} {...props}>
<Card.Body className="d-flex flex-column gap-3">
<Card.Title as="h3" className="h5">
<a target="_blank" href={html_url} rel="noreferrer">
{full_name}
</a>
</Card.Title>

<nav className="flex-fill">
{topics.map(topic => (
<Badge
key={topic}
className="me-1 text-decoration-none"
bg={text2color(topic, ['light'])}
as="a"
target="_blank"
href={`https://github.com/topics/${topic}`}
>
{topic}
</Badge>
))}
</nav>
<Row as="ul" className="list-unstyled g-4" xs={4}>
{languages.map(language => (
<Col key={language} as="li">
<GitLogo name={language} />
</Col>
))}
</Row>
<Card.Text>{description}</Card.Text>
</Card.Body>
<Card.Footer className="d-flex justify-content-between align-items-center">
{homepage && (
<Button variant="success" target="_blank" href={homepage}>
{t('home_page')}
</Button>
)}
</Card.Footer>
</Card>
);
},
);
10 changes: 5 additions & 5 deletions components/LanguageMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { Option, Select } from 'idea-react';
import { observer } from 'mobx-react';
import { FC } from 'react';
import { FC, useContext } from 'react';

import { i18n, LanguageName } from '../models/Translation';
import { I18nContext, LanguageName } from '../models/Translation';

const LanguageMenu: FC = observer(() => {
const { currentLanguage } = i18n;
const i18n = useContext(I18nContext);

return (
<Select
value={currentLanguage}
onChange={key => i18n.changeLanguage(key as typeof currentLanguage)}
value={i18n.currentLanguage}
onChange={key => i18n.loadLanguages(key as typeof i18n.currentLanguage)}
>
{Object.entries(LanguageName).map(([key, name]) => (
<Option key={key} value={key}>
Expand Down
5 changes: 5 additions & 0 deletions components/LightSwitch.module.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.switch :global {
.form-check-input:checked {
border-color: white;
}
}
28 changes: 28 additions & 0 deletions components/LightSwitch.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Icon } from 'idea-react';
import { observer } from 'mobx-react';
import { FC, HTMLAttributes } from 'react';
import { Form } from 'react-bootstrap';

import systemStore from '../models/System';
import styles from './LightSwitch.module.less';

const LightSwitch: FC<HTMLAttributes<HTMLDivElement>> = observer(
({ className = '', ...props }) => (
<div
className={`d-flex align-items-center text-white ${className}`}
{...props}
>
<Icon name="moon" />

<div className="ps-2 pe-1">
<Form.Switch
className={styles.switch}
checked={systemStore.colorScheme === 'light'}
onClick={systemStore.toggleColorScheme}
/>
</div>
<Icon name="sun" />
</div>
),
);
export default LightSwitch;
85 changes: 48 additions & 37 deletions components/MainNavigator.tsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,52 @@
import { observer } from 'mobx-react';
import dynamic from 'next/dynamic';
import { FC } from 'react';
import { FC, useContext } from 'react';
import { Container, Nav, Navbar } from 'react-bootstrap';

import { t } from '../models/Translation';

const LanguageMenu = dynamic(import('./LanguageMenu'), { ssr: false });

const Name = process.env.NEXT_PUBLIC_SITE_NAME || '';

export const MainNavigator: FC = observer(() => (
<Navbar bg="primary" variant="dark" fixed="top" expand="sm" collapseOnSelect>
<Container>
<Navbar.Brand href="/">{Name}</Navbar.Brand>

<Navbar.Toggle aria-controls="navbar-inner" />

<Navbar.Collapse id="navbar-inner">
<Nav className="me-auto">
<Nav.Link href="/article">{t('article')}</Nav.Link>

<Nav.Link href="/component">{t('component')}</Nav.Link>

<Nav.Link href="/pagination">{t('pagination')}</Nav.Link>

<Nav.Link href="/scroll-list">{t('scroll_list')}</Nav.Link>

<Nav.Link
target="_blank"
href="https://github.com/idea2app/Next-Bootstrap-TS"
>
{t('source_code')}
</Nav.Link>
</Nav>

<LanguageMenu />
</Navbar.Collapse>
</Container>
</Navbar>
));
import { Name } from '../models/configuration';
import { I18nContext } from '../models/Translation';

const LightSwitch = dynamic(() => import('./LightSwitch'), { ssr: false }),
LanguageMenu = dynamic(() => import('./LanguageMenu'), { ssr: false });

export const MainNavigator: FC = observer(() => {
const { t } = useContext(I18nContext);

return (
<Navbar
bg="primary"
variant="dark"
fixed="top"
expand="sm"
collapseOnSelect
>
<Container>
<Navbar.Brand href="/">{Name}</Navbar.Brand>

<Navbar.Toggle aria-controls="navbar-inner" />

<Navbar.Collapse id="navbar-inner">
<Nav className="me-auto">
<Nav.Link href="/article">{t('article')}</Nav.Link>

<Nav.Link href="/component">{t('component')}</Nav.Link>

<Nav.Link href="/pagination">{t('pagination')}</Nav.Link>

<Nav.Link href="/scroll-list">{t('scroll_list')}</Nav.Link>

<Nav.Link
target="_blank"
href="https://github.com/idea2app/Next-Bootstrap-TS"
>
{t('source_code')}
</Nav.Link>
</Nav>

<LightSwitch className="my-3 my-sm-0 mx-sm-3" />
<LanguageMenu />
</Navbar.Collapse>
</Container>
</Navbar>
);
});
Loading