Skip to content

Commit df14cd9

Browse files
authored
[add] System model & Light Switch component (#52)
1 parent 27f86d4 commit df14cd9

29 files changed

+2582
-1532
lines changed

.npmrc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1+
public-hoist-pattern[] = *import-in-the-middle*
2+
public-hoist-pattern[] = *require-in-the-middle*
13
auto-install-peers = false

README.md

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@
1414
- Component suite: [Bootstrap v5][4]
1515
- PWA framework: [Workbox v6][5]
1616
- State management: [MobX v6][11]
17-
- CI / CD: GitHub [Actions][12] + [Vercel][13]
18-
- Monitor service: [Sentry][14]
17+
- API router: [Koa 2][12]
18+
- CI / CD: GitHub [Actions][13] + [Vercel][14]
19+
- Monitor service: [Sentry][15]
1920

2021
## Major examples
2122

@@ -31,20 +32,20 @@
3132

3233
1. Install GitHub apps in your organization or account:
3334

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

37-
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
38+
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
3839

3940
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
4041

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

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

45-
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
46+
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
4647

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

4950
## Getting Started
5051

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

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

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

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

6667
## Learn More
6768

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

70-
- [Next.js Documentation][25] - learn about Next.js features and API.
71-
- [Learn Next.js][26] - an interactive Next.js tutorial.
71+
- [Next.js Documentation][26] - learn about Next.js features and API.
72+
- [Learn Next.js][27] - an interactive Next.js tutorial.
7273

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

7576
## Deployment
7677

7778
### Environment variables
7879

7980
| name | file | description |
8081
| :----------------------: | :----------: | :---------------------: |
81-
| `SENTRY_AUTH_TOKEN` | `.env.local` | [Official document][28] |
82-
| `SENTRY_ORG` | `.env` | [Official document][29] |
83-
| `SENTRY_PROJECT` | `.env` | [Official document][29] |
84-
| `NEXT_PUBLIC_SENTRY_DSN` | `.env` | [Official document][30] |
82+
| `SENTRY_AUTH_TOKEN` | `.env.local` | [Official document][29] |
83+
| `SENTRY_ORG` | `.env` | [Official document][30] |
84+
| `SENTRY_PROJECT` | `.env` | [Official document][30] |
85+
| `NEXT_PUBLIC_SENTRY_DSN` | `.env` | [Official document][31] |
8586

8687
### Vercel
8788

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

90-
Check out our [Next.js deployment documentation][31] for more details.
91+
Check out our [Next.js deployment documentation][32] for more details.
9192

9293
### Docker
9394

@@ -107,23 +108,24 @@ pnpm container
107108
[9]: https://gitpod.io/?autostart=true#https://github.com/idea2app/Next-Bootstrap-ts
108109
[10]: https://mdxjs.com/
109110
[11]: https://mobx.js.org/
110-
[12]: https://github.com/features/actions
111-
[13]: https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme
112-
[14]: https://sentry.io/
113-
[15]: https://github.com/apps/settings
114-
[16]: https://pullrequestbadge.com/
115-
[17]: https://code.visualstudio.com/
116-
[18]: https://github.com/new?template_name=Next-Bootstrap-ts&template_owner=idea2app
117-
[19]: https://github.com/idea2app/Next-Bootstrap-ts/blob/80967ed49045af9dbcf4d3695a2c39d53a6f71f1/.github/workflows/pull-request.yml#L9-L11
118-
[20]: https://github.com/idea2app/Next-Bootstrap-ts/settings/secrets/actions
119-
[21]: https://github.com/kaiyuanshe/kaiyuanshe.github.io/blob/bb4675a56bf1d6b207231313da5ed0af7cf0ebd6/.github/workflows/pull-request.yml#L32-L56
120-
[22]: https://github.com/idea2app/Next-Bootstrap-ts/issues/new/choose
121-
[23]: https://github.com/idea2app/Next-Bootstrap-ts/projects
122-
[24]: https://nextjs.org/docs/api-routes/introduction
123-
[25]: https://nextjs.org/docs
124-
[26]: https://nextjs.org/learn
125-
[27]: https://github.com/vercel/next.js/
126-
[28]: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#use-configuration-files-for-source-map-upload
127-
[29]: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#use-environment-variables
128-
[30]: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#create-initialization-config-files
129-
[31]: https://nextjs.org/docs/deployment
111+
[12]: https://koajs.com/
112+
[13]: https://github.com/features/actions
113+
[14]: https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme
114+
[15]: https://sentry.io/
115+
[16]: https://github.com/apps/settings
116+
[17]: https://pullrequestbadge.com/
117+
[18]: https://code.visualstudio.com/
118+
[19]: https://github.com/new?template_name=Next-Bootstrap-ts&template_owner=idea2app
119+
[20]: https://github.com/idea2app/Next-Bootstrap-ts/blob/80967ed49045af9dbcf4d3695a2c39d53a6f71f1/.github/workflows/pull-request.yml#L9-L11
120+
[21]: https://github.com/idea2app/Next-Bootstrap-ts/settings/secrets/actions
121+
[22]: https://github.com/FreeCodeCamp-Chengdu/FreeCodeCamp-Chengdu.github.io/blob/8df9944449002758f7ec809deeb260ce08182259/.github/workflows/main.yml#L34-L63
122+
[23]: https://github.com/idea2app/Next-Bootstrap-ts/issues/new/choose
123+
[24]: https://github.com/idea2app/Next-Bootstrap-ts/projects
124+
[25]: https://nextjs.org/docs/api-routes/introduction
125+
[26]: https://nextjs.org/docs
126+
[27]: https://nextjs.org/learn
127+
[28]: https://github.com/vercel/next.js/
128+
[29]: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#use-configuration-files-for-source-map-upload
129+
[30]: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#use-environment-variables
130+
[31]: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#create-initialization-config-files
131+
[32]: https://nextjs.org/docs/deployment

components/Git/Card.tsx

Lines changed: 46 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { text2color } from 'idea-react';
22
import { GitRepository } from 'mobx-github';
33
import { observer } from 'mobx-react';
4-
import { FC } from 'react';
4+
import { FC, useContext } from 'react';
55
import { Badge, Button, Card, CardProps, Col, Row } from 'react-bootstrap';
66

7-
import { t } from '../../models/Translation';
7+
import { I18nContext } from '../../models/Translation';
88
import { GitLogo } from './Logo';
99

1010
export interface GitCardProps
@@ -24,45 +24,49 @@ export const GitCard: FC<GitCardProps> = observer(
2424
description,
2525
homepage,
2626
...props
27-
}) => (
28-
<Card className={className} {...props}>
29-
<Card.Body className="d-flex flex-column gap-3">
30-
<Card.Title as="h3" className="h5">
31-
<a target="_blank" href={html_url} rel="noreferrer">
32-
{full_name}
33-
</a>
34-
</Card.Title>
27+
}) => {
28+
const { t } = useContext(I18nContext);
3529

36-
<nav className="flex-fill">
37-
{topics.map(topic => (
38-
<Badge
39-
key={topic}
40-
className="me-1 text-decoration-none"
41-
bg={text2color(topic, ['light'])}
42-
as="a"
43-
target="_blank"
44-
href={`https://github.com/topics/${topic}`}
45-
>
46-
{topic}
47-
</Badge>
48-
))}
49-
</nav>
50-
<Row as="ul" className="list-unstyled g-4" xs={4}>
51-
{languages.map(language => (
52-
<Col key={language} as="li">
53-
<GitLogo name={language} />
54-
</Col>
55-
))}
56-
</Row>
57-
<Card.Text>{description}</Card.Text>
58-
</Card.Body>
59-
<Card.Footer className="d-flex justify-content-between align-items-center">
60-
{homepage && (
61-
<Button variant="success" target="_blank" href={homepage}>
62-
{t('home_page')}
63-
</Button>
64-
)}
65-
</Card.Footer>
66-
</Card>
67-
),
30+
return (
31+
<Card className={className} {...props}>
32+
<Card.Body className="d-flex flex-column gap-3">
33+
<Card.Title as="h3" className="h5">
34+
<a target="_blank" href={html_url} rel="noreferrer">
35+
{full_name}
36+
</a>
37+
</Card.Title>
38+
39+
<nav className="flex-fill">
40+
{topics.map(topic => (
41+
<Badge
42+
key={topic}
43+
className="me-1 text-decoration-none"
44+
bg={text2color(topic, ['light'])}
45+
as="a"
46+
target="_blank"
47+
href={`https://github.com/topics/${topic}`}
48+
>
49+
{topic}
50+
</Badge>
51+
))}
52+
</nav>
53+
<Row as="ul" className="list-unstyled g-4" xs={4}>
54+
{languages.map(language => (
55+
<Col key={language} as="li">
56+
<GitLogo name={language} />
57+
</Col>
58+
))}
59+
</Row>
60+
<Card.Text>{description}</Card.Text>
61+
</Card.Body>
62+
<Card.Footer className="d-flex justify-content-between align-items-center">
63+
{homepage && (
64+
<Button variant="success" target="_blank" href={homepage}>
65+
{t('home_page')}
66+
</Button>
67+
)}
68+
</Card.Footer>
69+
</Card>
70+
);
71+
},
6872
);

components/LanguageMenu.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
import { Option, Select } from 'idea-react';
22
import { observer } from 'mobx-react';
3-
import { FC } from 'react';
3+
import { FC, useContext } from 'react';
44

5-
import { i18n, LanguageName } from '../models/Translation';
5+
import { I18nContext, LanguageName } from '../models/Translation';
66

77
const LanguageMenu: FC = observer(() => {
8-
const { currentLanguage } = i18n;
8+
const i18n = useContext(I18nContext);
99

1010
return (
1111
<Select
12-
value={currentLanguage}
13-
onChange={key => i18n.changeLanguage(key as typeof currentLanguage)}
12+
value={i18n.currentLanguage}
13+
onChange={key => i18n.loadLanguages(key as typeof i18n.currentLanguage)}
1414
>
1515
{Object.entries(LanguageName).map(([key, name]) => (
1616
<Option key={key} value={key}>

components/LightSwitch.module.less

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.switch :global {
2+
.form-check-input:checked {
3+
border-color: white;
4+
}
5+
}

components/LightSwitch.tsx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { Icon } from 'idea-react';
2+
import { observer } from 'mobx-react';
3+
import { FC, HTMLAttributes } from 'react';
4+
import { Form } from 'react-bootstrap';
5+
6+
import systemStore from '../models/System';
7+
import styles from './LightSwitch.module.less';
8+
9+
const LightSwitch: FC<HTMLAttributes<HTMLDivElement>> = observer(
10+
({ className = '', ...props }) => (
11+
<div
12+
className={`d-flex align-items-center text-white ${className}`}
13+
{...props}
14+
>
15+
<Icon name="moon" />
16+
17+
<div className="ps-2 pe-1">
18+
<Form.Switch
19+
className={styles.switch}
20+
checked={systemStore.colorScheme === 'light'}
21+
onClick={systemStore.toggleColorScheme}
22+
/>
23+
</div>
24+
<Icon name="sun" />
25+
</div>
26+
),
27+
);
28+
export default LightSwitch;

components/MainNavigator.tsx

Lines changed: 48 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,52 @@
11
import { observer } from 'mobx-react';
22
import dynamic from 'next/dynamic';
3-
import { FC } from 'react';
3+
import { FC, useContext } from 'react';
44
import { Container, Nav, Navbar } from 'react-bootstrap';
55

6-
import { t } from '../models/Translation';
7-
8-
const LanguageMenu = dynamic(import('./LanguageMenu'), { ssr: false });
9-
10-
const Name = process.env.NEXT_PUBLIC_SITE_NAME || '';
11-
12-
export const MainNavigator: FC = observer(() => (
13-
<Navbar bg="primary" variant="dark" fixed="top" expand="sm" collapseOnSelect>
14-
<Container>
15-
<Navbar.Brand href="/">{Name}</Navbar.Brand>
16-
17-
<Navbar.Toggle aria-controls="navbar-inner" />
18-
19-
<Navbar.Collapse id="navbar-inner">
20-
<Nav className="me-auto">
21-
<Nav.Link href="/article">{t('article')}</Nav.Link>
22-
23-
<Nav.Link href="/component">{t('component')}</Nav.Link>
24-
25-
<Nav.Link href="/pagination">{t('pagination')}</Nav.Link>
26-
27-
<Nav.Link href="/scroll-list">{t('scroll_list')}</Nav.Link>
28-
29-
<Nav.Link
30-
target="_blank"
31-
href="https://github.com/idea2app/Next-Bootstrap-TS"
32-
>
33-
{t('source_code')}
34-
</Nav.Link>
35-
</Nav>
36-
37-
<LanguageMenu />
38-
</Navbar.Collapse>
39-
</Container>
40-
</Navbar>
41-
));
6+
import { Name } from '../models/configuration';
7+
import { I18nContext } from '../models/Translation';
8+
9+
const LightSwitch = dynamic(() => import('./LightSwitch'), { ssr: false }),
10+
LanguageMenu = dynamic(() => import('./LanguageMenu'), { ssr: false });
11+
12+
export const MainNavigator: FC = observer(() => {
13+
const { t } = useContext(I18nContext);
14+
15+
return (
16+
<Navbar
17+
bg="primary"
18+
variant="dark"
19+
fixed="top"
20+
expand="sm"
21+
collapseOnSelect
22+
>
23+
<Container>
24+
<Navbar.Brand href="/">{Name}</Navbar.Brand>
25+
26+
<Navbar.Toggle aria-controls="navbar-inner" />
27+
28+
<Navbar.Collapse id="navbar-inner">
29+
<Nav className="me-auto">
30+
<Nav.Link href="/article">{t('article')}</Nav.Link>
31+
32+
<Nav.Link href="/component">{t('component')}</Nav.Link>
33+
34+
<Nav.Link href="/pagination">{t('pagination')}</Nav.Link>
35+
36+
<Nav.Link href="/scroll-list">{t('scroll_list')}</Nav.Link>
37+
38+
<Nav.Link
39+
target="_blank"
40+
href="https://github.com/idea2app/Next-Bootstrap-TS"
41+
>
42+
{t('source_code')}
43+
</Nav.Link>
44+
</Nav>
45+
46+
<LightSwitch className="my-3 my-sm-0 mx-sm-3" />
47+
<LanguageMenu />
48+
</Navbar.Collapse>
49+
</Container>
50+
</Navbar>
51+
);
52+
});

0 commit comments

Comments
 (0)