Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: umi blocks #61

Merged
merged 1 commit into from
Dec 8, 2023
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
7 changes: 7 additions & 0 deletions examples/alita/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,20 @@ import { defineConfig } from 'alita';

export default defineConfig({
presets: [require.resolve('@mongchhi/preset-mongchhi')],
plugins: [require.resolve('@mongchhi/plugin-blocks')],
appType: 'h5',
keepalive: [/users/],
aconsole: {
console: {},
inspx: {},
},
mobileLayout: 'mobile5',
block: {
defaultGitUrl: 'https://github.com/ant-design/pro-blocks',
npmClient: 'pnpm',
closeFastGithub: true,
homedir: false,
},
mfsu: false,
hash: false,
});
5 changes: 5 additions & 0 deletions examples/alita/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,20 @@
"name": "@examples/alita",
"private": true,
"scripts": {
"block": "alita block add https://github.com/ant-design/pro-blocks/tree/feat-antd5/UserRegister --path=/user/register --skip-dependencies --page --branch=feat-antd5 --skip-modify-routes",
"build": "alita build",
"dev": "alita dev",
"start": "alita dev"
},
"dependencies": {
"@alita/flow": "*",
"@mongchhi/plugin-blocks": "workspace:*",
"@mongchhi/preset-mongchhi": "workspace:*",
"alita": "^3.3.7",
"antd-mobile": "^5.15.1",
"classnames": "^2.2.6",
"moment": "^2.22.2",
"nzh": "^1.0.3",
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
Expand Down
18 changes: 18 additions & 0 deletions examples/alita/src/pages/asd/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Button, Result } from 'antd';
import { Link } from 'umi';

export default () => (
<Result
status="403"
title="403"
style={{
background: 'none',
}}
subTitle="Sorry, you don't have access to this page."
extra={
<Link to="/">
<Button type="primary">Back to home</Button>
</Link>
}
/>
);
10 changes: 10 additions & 0 deletions examples/alita/src/pages/user/register/_mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// @ts-nocheck
import type { Request, Response } from 'express';

export default {
'POST /api/register': (_: Request, res: Response) => {
res.send({
data: { status: 'ok', currentAuthority: 'user' },
});
},
};
306 changes: 306 additions & 0 deletions examples/alita/src/pages/user/register/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,306 @@
import {
Button,
Col,
Form,
Input,
message,
Popover,
Progress,
Row,
Select,
} from 'antd';
import type { Store } from 'antd/es/form/interface';
import type { FC } from 'react';
import { useEffect, useState } from 'react';
import { history, Link, useRequest } from 'umi';
import type { StateType } from './service';
import { fakeRegister } from './service';

import useStyles from './style.style';

const FormItem = Form.Item;
const { Option } = Select;
const InputGroup = Input.Group;

const passwordProgressMap: {
ok: 'success';
pass: 'normal';
poor: 'exception';
} = {
ok: 'success',
pass: 'normal',
poor: 'exception',
};

const Register: FC = () => {
const { styles } = useStyles();

const passwordStatusMap = {
ok: (
<div className={styles.success}>
<span>强度:强</span>
</div>
),

pass: (
<div className={styles.warning}>
<span>强度:中</span>
</div>
),

poor: (
<div className={styles.error}>
<span>强度:太短</span>
</div>
),
};
const [count, setCount]: [number, any] = useState(0);
const [visible, setVisible]: [boolean, any] = useState(false);
const [prefix, setPrefix]: [string, any] = useState('86');
const [popover, setPopover]: [boolean, any] = useState(false);
const confirmDirty = false;
let interval: number | undefined;
const [form] = Form.useForm();

useEffect(
() => () => {
clearInterval(interval);
},
[interval],
);

const onGetCaptcha = () => {
let counts = 59;
setCount(counts);
interval = window.setInterval(() => {
counts -= 1;
setCount(counts);
if (counts === 0) {
clearInterval(interval);
}
}, 1000);
};

const getPasswordStatus = () => {
const value = form.getFieldValue('password');
if (value && value.length > 9) {
return 'ok';
}
if (value && value.length > 5) {
return 'pass';
}
return 'poor';
};

const { loading: submitting, run: register } = useRequest<{
data: StateType;
}>(fakeRegister, {
manual: true,
onSuccess: (data, params) => {
if (data.status === 'ok') {
message.success('注册成功!');
history.push({
pathname: `/user/register-result?account=${params.email}`,
});
}
},
});
const onFinish = (values: Store) => {
register(values);
};

const checkConfirm = (_: any, value: string) => {
const promise = Promise;
if (value && value !== form.getFieldValue('password')) {
return promise.reject('两次输入的密码不匹配!');
}
return promise.resolve();
};

const checkPassword = (_: any, value: string) => {
const promise = Promise;
// 没有值的情况
if (!value) {
setVisible(!!value);
return promise.reject('请输入密码!');
}
// 有值的情况
if (!visible) {
setVisible(!!value);
}
setPopover(!popover);
if (value.length < 6) {
return promise.reject('');
}
if (value && confirmDirty) {
form.validateFields(['confirm']);
}
return promise.resolve();
};

const changePrefix = (value: string) => {
setPrefix(value);
};

const renderPasswordProgress = () => {
const value = form.getFieldValue('password');
const passwordStatus = getPasswordStatus();
return value && value.length ? (
// @ts-ignore
<div className={styles[`progress-${passwordStatus}`]}>
<Progress
status={passwordProgressMap[passwordStatus]}
strokeWidth={6}
percent={value.length * 10 > 100 ? 100 : value.length * 10}
showInfo={false}
/>
</div>
) : null;
};

return (
<div className={styles.main}>
<h3>注册</h3>
<Form form={form} name="UserRegister" onFinish={onFinish}>
<FormItem
name="mail"
rules={[
{
required: true,
message: '请输入邮箱地址!',
},
{
type: 'email',
message: '邮箱地址格式错误!',
},
]}
>
<Input size="large" placeholder="邮箱" />
</FormItem>
<Popover
getPopupContainer={(node) => {
if (node && node.parentNode) {
return node.parentNode as HTMLElement;
}
return node;
}}
content={
visible && (
<div style={{ padding: '4px 0' }}>
{passwordStatusMap[getPasswordStatus()]}
{renderPasswordProgress()}
<div style={{ marginTop: 10 }}>
<span>请至少输入 6 个字符。请不要使用容易被猜到的密码。</span>
</div>
</div>
)
}
overlayStyle={{ width: 240 }}
placement="right"
visible={visible}
>
<FormItem
name="password"
className={
form.getFieldValue('password') &&
form.getFieldValue('password').length > 0 &&
styles.password
}
rules={[
{
validator: checkPassword,
},
]}
>
<Input
size="large"
type="password"
placeholder="至少6位密码,区分大小写"
/>
</FormItem>
</Popover>
<FormItem
name="confirm"
rules={[
{
required: true,
message: '确认密码',
},
{
validator: checkConfirm,
},
]}
>
<Input size="large" type="password" placeholder="确认密码" />
</FormItem>
<InputGroup compact>
<Select
size="large"
value={prefix}
onChange={changePrefix}
style={{ width: '20%' }}
>
<Option value="86">+86</Option>
<Option value="87">+87</Option>
</Select>
<FormItem
style={{ width: '80%' }}
name="mobile"
rules={[
{
required: true,
message: '请输入手机号!',
},
{
pattern: /^\d{11}$/,
message: '手机号格式错误!',
},
]}
>
<Input size="large" placeholder="手机号" />
</FormItem>
</InputGroup>
<Row gutter={8}>
<Col span={16}>
<FormItem
name="captcha"
rules={[
{
required: true,
message: '请输入验证码!',
},
]}
>
<Input size="large" placeholder="验证码" />
</FormItem>
</Col>
<Col span={8}>
<Button
size="large"
disabled={!!count}
className={styles.getCaptcha}
onClick={onGetCaptcha}
>
{count ? `${count} s` : '获取验证码'}
</Button>
</Col>
</Row>
<FormItem>
<Button
size="large"
loading={submitting}
className={styles.submit}
type="primary"
htmlType="submit"
>
<span>注册</span>
</Button>
<Link className={styles.login} to="/user/login">
<span>使用已有账户登录</span>
</Link>
</FormItem>
</Form>
</div>
);
};
export default Register;
Loading
Loading