Skip to content

Commit

Permalink
[optimize] upgrade to MobX 6, React 18 & Next.js 13 (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
TechQuery authored Aug 31, 2023
1 parent a692af6 commit f4cfcd5
Show file tree
Hide file tree
Showing 18 changed files with 1,273 additions and 1,257 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
## Technology stack

- Language: [TypeScript v5][2]
- Component engine: [Nextjs v12][3]
- Component engine: [Nextjs v13][3]
- Component suite: [Bootstrap v5][4]
- PWA framework: [Workbox v6][5]
- State management: [MobX][9]
- State management: [MobX v6][9]
- CI / CD: GitHub [Actions][11] + [Vercel][12]

## Getting Started
Expand Down Expand Up @@ -55,7 +55,7 @@ pnpm pack-image
pnpm container
```

[1]: https://reactjs.org/
[1]: https://react.dev/
[2]: https://www.typescriptlang.org/
[3]: https://nextjs.org/
[4]: https://getbootstrap.com/
Expand Down
6 changes: 4 additions & 2 deletions components/Address/Card.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { AddressOutput } from '@ideamall/data-model';
import { FC } from 'react';
import { FC, PropsWithChildren } from 'react';
import { Card, CardProps } from 'react-bootstrap';

export interface AddressProps
Expand Down Expand Up @@ -43,7 +43,9 @@ export const Address: FC<AddressProps> = ({
</address>
);

export type AddressCardProps = AddressOutput & Pick<CardProps, 'as'>;
export type AddressCardProps = PropsWithChildren<
AddressOutput & Pick<CardProps, 'as'>
>;

export const AddressCard: FC<AddressCardProps> = ({
as,
Expand Down
7 changes: 6 additions & 1 deletion components/Address/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { AddressOutput } from '@ideamall/data-model';
import { observable } from 'mobx';
import { makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import {
Field,
Expand All @@ -23,6 +23,11 @@ export interface AddressListProps

@observer
export class AddressList extends PureComponent<AddressListProps> {
constructor(props: AddressListProps) {
super(props);
makeObservable(this);
}

@observable
creating = false;

Expand Down
17 changes: 9 additions & 8 deletions components/AdminFrame.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import { Role } from '@ideamall/data-model';
import { Icon } from 'idea-react';
import { observer } from 'mobx-react';
import { PureComponent } from 'react';
import dynamic from 'next/dynamic';
import { PropsWithChildren, PureComponent } from 'react';
import { Container, Nav } from 'react-bootstrap';

import { i18n } from '../models/Translation';
import userStore from '../models/User';
import { MainNavigator } from './MainNavigator';
import { PageHead } from './PageHead';
import { SessionBox } from './SessionBox';

const { location } = globalThis,
const SessionBox = dynamic(() => import('./SessionBox'), { ssr: false }),
{ location } = globalThis,
{ t } = i18n;

@observer
export class AdminFrame extends PureComponent {
export class AdminFrame extends PureComponent<PropsWithChildren> {
get routes() {
return [
{ path: '', icon: 'clipboard-data', title: t('dashboard') },
Expand Down Expand Up @@ -64,15 +65,15 @@ export class AdminFrame extends PureComponent {
)
return;

var { path, active } = this.routeOf(path);
const route = this.routeOf(path);

return (
<Nav.Link
className={`text-nowrap rounded-3 ${
active ? 'bg-primary text-white' : ''
route.active ? 'bg-primary text-white' : ''
}`}
href={path}
key={path}
href={route.path}
key={route.path}
>
<Icon className="me-3" name={icon} />
<span className="d-none d-sm-inline">{title}</span>
Expand Down
7 changes: 6 additions & 1 deletion components/Git/Logo.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { observable } from 'mobx';
import { makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import { PureComponent } from 'react';
import { Image } from 'react-bootstrap';
Expand All @@ -9,6 +9,11 @@ export interface GitLogoProps {

@observer
export class GitLogo extends PureComponent<GitLogoProps> {
constructor(props: GitLogoProps) {
super(props);
makeObservable(this);
}

@observable
path = '';

Expand Down
20 changes: 15 additions & 5 deletions components/Goods/StyleEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { GoodsStyle } from '@ideamall/data-model';
import { computed, observable } from 'mobx';
import { computed, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import { observePropsState } from 'mobx-react-helper';
import { BadgeInput } from 'mobx-restful-table';
import { MouseEvent, PureComponent } from 'react';
import { Component, MouseEvent } from 'react';
import { Button, Col, Form, Row } from 'react-bootstrap';

import { i18n } from '../../models/Translation';
Expand All @@ -16,17 +17,26 @@ export interface GoodsStyleEditorProps {
}

@observer
export class GoodsStyleEditor extends PureComponent<GoodsStyleEditorProps> {
@observePropsState
export class GoodsStyleEditor extends Component<GoodsStyleEditorProps> {
constructor(props: GoodsStyleEditorProps) {
super(props);
makeObservable(this);
}

declare observedProps: GoodsStyleEditorProps;

@observable
innerValue = this.props.defaultValue || [];

@computed
get value() {
return this.props.value || this.innerValue;
return this.observedProps.value || this.innerValue;
}

@computed
get controlled() {
return Array.isArray(this.props.value);
return Array.isArray(this.observedProps.value);
}

handleCreate = (event: MouseEvent<HTMLButtonElement>) => {
Expand Down
10 changes: 5 additions & 5 deletions components/MainNavigator.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Option, Select } from 'idea-react';
import { observer } from 'mobx-react';
import Link from 'next/link';
import dynamic from 'next/dynamic';
import { FC } from 'react';
import {
Container,
Expand All @@ -11,7 +11,8 @@ import {
} from 'react-bootstrap';

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

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

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

Expand All @@ -37,9 +38,8 @@ export const MainNavigator: FC<MainNavigatorProps> = observer(

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

<Nav.Link target="_blank" href="https://github.com/IdeaMall/PWA">
{t('source_code')}
</Nav.Link>
Expand Down
9 changes: 4 additions & 5 deletions components/PageHead.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import Head from 'next/head';
import type { FC } from 'react';
import type { FC, PropsWithChildren } from 'react';

export interface PageHeadProps {
export type PageHeadProps = PropsWithChildren<{
title?: string;
description?: string;
}
}>;

const Name = process.env.NEXT_PUBLIC_SITE_NAME,
Summary = process.env.NEXT_PUBLIC_SITE_SUMMARY;
Expand All @@ -16,8 +16,7 @@ export const PageHead: FC<PageHeadProps> = ({
}) => (
<Head>
<title>
{title}
{title && ' - '}
{title && `${title} - `}
{Name}
</title>

Expand Down
14 changes: 9 additions & 5 deletions components/SessionBox.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
import { Role } from '@ideamall/data-model';
import { computed } from 'mobx';
import { observer } from 'mobx-react';
import { observePropsState } from 'mobx-react-helper';
import Head from 'next/head';
import { MouseEvent, PureComponent } from 'react';
import { Component, MouseEvent, PropsWithChildren } from 'react';

import userStore, { guard } from '../models/User';

export interface SessionBoxProps {
export type SessionBoxProps = PropsWithChildren<{
className?: string;
autoCover?: boolean;
roles?: Role[];
}
}>;

@observer
export class SessionBox extends PureComponent<SessionBoxProps> {
@observePropsState
export default class SessionBox extends Component<SessionBoxProps> {
declare observedProps: SessionBoxProps;

@computed
get authorized() {
const { roles } = this.props,
const { roles } = this.observedProps,
{ session } = userStore;

return !!(roles
Expand Down
33 changes: 17 additions & 16 deletions components/UserMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
import { Role } from '@ideamall/data-model';
import { observer } from 'mobx-react';
import dynamic from 'next/dynamic';
import { FC } from 'react';
import { Button, Dropdown, DropdownButton } from 'react-bootstrap';

import { i18n } from '../models/Translation';
import userStore from '../models/User';
import { SessionBox } from './SessionBox';

const { t } = i18n;
const SessionBox = dynamic(() => import('./SessionBox'), { ssr: false }),
{ t } = i18n;

export const UserMenu: FC = observer(() => {
const UserMenu: FC = observer(() => {
const { session } = userStore;

return (
<SessionBox>
{session ? (
<DropdownButton title={session.nickName || session.mobilePhone}>
{!session.roles?.includes(Role.Client) && (
<Dropdown.Item href="/admin">{t('dashboard')}</Dropdown.Item>
)}
<Dropdown.Item onClick={() => userStore.signOut()}>
{t('sign_out')}
</Dropdown.Item>
</DropdownButton>
) : (
<Button>{t('sign_in')}</Button>
return session ? (
<DropdownButton title={session.nickName || session.mobilePhone}>
{!session.roles?.includes(Role.Client) && (
<Dropdown.Item href="/admin">{t('dashboard')}</Dropdown.Item>
)}
<Dropdown.Item onClick={() => userStore.signOut()}>
{t('sign_out')}
</Dropdown.Item>
</DropdownButton>
) : (
<SessionBox>
<Button>{t('sign_in')}</Button>
</SessionBox>
);
});

export default UserMenu;
7 changes: 6 additions & 1 deletion models/Goods.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import { GoodsItemOutput, GoodsOutput } from '@ideamall/data-model';
import { observable } from 'mobx';
import { makeObservable, observable } from 'mobx';

import { TableModel } from './Base';
import userStore from './User';

export class GoodsModel extends TableModel<GoodsOutput> {
constructor() {
super();
makeObservable(this);
}

client = userStore.client;
baseURI = 'goods';

Expand Down
7 changes: 6 additions & 1 deletion models/Statistic.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import { StatisticSummary } from '@ideamall/data-model';
import { observable } from 'mobx';
import { makeObservable, observable } from 'mobx';
import { BaseModel, toggle } from 'mobx-restful';

import userStore from './User';

export class StatisticModel extends BaseModel {
constructor() {
super();
makeObservable(this);
}

baseURI = 'statistic';
client = userStore.client;

Expand Down
7 changes: 6 additions & 1 deletion models/User.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Guard } from '@authing/guard';
import { UserOutput } from '@ideamall/data-model';
import { HTTPClient } from 'koajax';
import { observable } from 'mobx';
import { makeObservable, observable } from 'mobx';
import { toggle } from 'mobx-restful';

import { API_Host, TableModel } from './Base';
Expand All @@ -14,6 +14,11 @@ export const guard = new Guard({
});

export class UserModel extends TableModel<UserOutput> {
constructor() {
super();
makeObservable(this);
}

baseURI = 'user';

@observable
Expand Down
6 changes: 1 addition & 5 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,4 @@ const { NODE_ENV } = process.env,
/**
* @type {import('next').NextConfig}
*/
module.exports = withPWA(
withLess({
reactStrictMode: true,
}),
);
module.exports = withPWA(withLess({}));
Loading

1 comment on commit f4cfcd5

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deploy preview for idea-mall ready!

✅ Preview
https://idea-mall-cgohi0ev2-techquery.vercel.app

Built with commit f4cfcd5.
This pull request is being automatically deployed with vercel-action

Please sign in to comment.