Commit e76dd32d authored by littleforest's avatar littleforest

feat: add chat pages

parent bf41e05b
export default [
{
name: 'chat',
path: '/chat',
component: './Chat',
layout: false,
},
{
path: '/user',
layout: false,
......
@import '~antd/es/style/variable.less';
@backGroundMainPrimary: #009b95;
@backGroundMainDefault: #f8f9fb;
@colorMainPrimary: #009b95;
@colorMainDefault: #999999;
@colorMainSubDefault: #666666;
html,
body,
#root {
......
.content {
width: 100%;
padding: 100px;
background: white;
.cardPadding {
margin: 16px 18px;
}
.CardContent {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
}
import { Layout } from 'antd';
import type { FC } from 'react';
import { FormattedMessage, useIntl } from 'umi';
import styles from './content.less';
import ProductionCard from './productionCard';
import ChatHeader from './header';
const { Content } = Layout;
interface ChatFirstContentProps {
onChange?: (text: string) => void;
}
const ChatFirstContent: FC<ChatFirstContentProps> = (props) => {
const { onChange } = props;
const cardList = [
{
title: '市场营销',
content:
'请为我编写一个杨过大战钢铁侠的额电影脚本,要足够精彩,细节丰富,好像好莱坞大片,有场景有对话,叨叨剧本要求',
onclick: (text: string) => {
onChange && onChange(text);
},
},
{
title: '技术文档',
content: '请为我们的新款智能手表撰写一份产品说明书,包括功能,使用方法和注意事项',
onclick: (text: string) => {
onChange && onChange(text);
},
},
{
title: '灵感提示',
content: '请为我们的新款智能手表一份产品说明书,包括功能,使用方法和注意事项',
onclick: (text: string) => {
onChange && onChange(text);
},
},
{
content: '请为我们的新款智能手表一份产品说明书,包括功能,使用方法和注意事项',
onclick: (text: string) => {
onChange && onChange(text);
},
},
{
content: '请为我们的新款智能手表一份产品说明书,包括功能,使用方法和注意事项',
onclick: (text: string) => {
onChange && onChange(text);
},
},
{
content: '请为我们的新款智能手表一份产品说明书,包括功能,使用方法和注意事项',
onclick: (text: string) => {
onChange && onChange(text);
},
},
{
content: '请为我们的新款智能手表一份产品说明书,包括功能,使用方法和注意事项',
onclick: (text: string) => {
onChange && onChange(text);
},
},
{
content: '请为我们的新款智能手表一份产品说明书,包括功能,使用方法和注意事项',
onclick: (text: string) => {
onChange && onChange(text);
},
},
{
content: '请为我们的新款智能手表一份产品说明书,包括功能,使用方法和注意事项',
onclick: (text: string) => {
onChange && onChange(text);
},
},
];
return (
<Content className={styles.content}>
<div className={styles.CardContent}>
{cardList.map((item, index) => {
return (
<div className={styles.cardPadding} key={`${item.title}-card-${index}`}>
<ProductionCard title={item.title} content={item.content} onChange={item.onclick} />
</div>
);
})}
</div>
</Content>
);
};
export default ChatFirstContent;
.footer {
position: fixed;
bottom: 0;
display: flex;
width: calc(100% - 200px);
height: 150px;
padding: 16px 180px;
background-color: white;
box-shadow: 0 2px 8px #f0f1f2;
.chatWrapper {
flex: 1;
padding: 0 16px 0 50px;
:global {
.ant-input:focus,
.ant-input:hover,
.ant-input-focused {
border-color: #009b95;
}
.ant-input:focus,
.ant-input-focused {
box-shadow: 0 0 0 2px #009b95;
}
}
}
.outputButtonWrapper {
width: 120px;
:global(.ant-btn-primary) {
background: #009b95;
border: solid 1px #009b95;
}
}
}
import { Layout, Input, Button, Form } from 'antd';
import styles from './footer.less';
const { Footer } = Layout;
const { Item } = Form;
function ChatFooter() {
return (
<Footer className={styles.footer}>
<div className={styles.chatWrapper}>
<Item name="chatInput">
<Input placeholder="在这里输入你想知道的问题,给我几句提示,我来帮你回答" size="large" />
</Item>
</div>
<div className={styles.outputButtonWrapper}>
<Item name="outputButton">
<Button type="primary" size="large">
发送
</Button>
</Item>
</div>
</Footer>
);
}
export default ChatFooter;
.header {
margin-top: 68px;
color: #333;
font-size: 32px;
line-height: 45px;
text-align: center;
.subTitle {
color: #999999;
font-weight: 400;
}
}
import { PageContainer } from '@ant-design/pro-components';
import { Alert, Card, Typography, Layout } from 'antd';
import React from 'react';
import styles from './header.less';
import ProductionCard from './productionCard';
const { Header } = Layout;
const { Title } = Typography;
const ChatHeader: React.FC = () => {
return (
<div className={styles.header}>
<Title level={1}>产品名称</Title>
<Title level={5} className={styles.subTitle}>
AI改变世界
</Title>
</div>
);
};
export default ChatHeader;
.CardWrapper {
width: 306px;
cursor: pointer;
&:hover .CardContent {
background-color: #0a7a73;
&:hover .content {
color: white;
}
&:hover .button {
color: #0a7a73;
background-color: white;
border: solid 1px white;
}
}
.title {
padding: 5px;
color: #333333;
font-weight: 600;
font-size: 22px;
line-height: 26px;
text-align: center;
}
.CardContent {
padding: 16px 24px;
background-color: #f8f9fb;
border-radius: 5px;
transition: all 0.25s;
.content {
height: 204px;
padding: 12px 8px;
color: #666666;
font-weight: 400;
font-size: 14px;
line-height: 28px;
}
.button {
width: 180px;
margin: 0 auto;
padding: 6px 24px;
color: #0a7a73;
font-size: 16px;
text-align: center;
border: solid 1px #0a7a73;
border-radius: 5px;
}
}
}
import type { ReactNode } from 'react';
import styles from './productionCard.less';
import classnames from 'classnames';
interface ProductionCardProps {
title?: string;
content: ReactNode;
onChange: (content: string) => void;
}
const ProductionCard = (props: ProductionCardProps) => {
const { title, content, onChange } = props;
const handleClick = () => {
onChange && onChange(content);
};
return (
<div className={classnames(styles.CardWrapper)}>
<div className={styles.title}>{title}</div>
<div className={styles.CardContent}>
<div className={styles.content}>{content}</div>
<div className={styles.button} onClick={handleClick}>
试一下看看
</div>
</div>
</div>
);
};
export default ProductionCard;
@import (reference) '~antd/es/style/themes/index';
.chatContent {
background: white !important;
}
import { Layout, Form } from 'antd';
import React, { useState } from 'react';
import { useIntl } from 'umi';
import styles from './index.less';
import ChatFirstContent from './components/content';
import ChatHeader from './components/header';
import ChatFooter from './components/footer';
const { Sider } = Layout;
const { Item } = Form;
const Chat: React.FC = () => {
const [chat, SetChat] = useState({
chatInput: '123123',
});
const onSend = (value: any) => {
console.log(value);
};
const onChange = (value: any) => {
console.log(value);
value?.chatInput && SetChat(value?.chatInput);
value?.firstInput && SetChat({ chatInput: value?.firstInput });
};
console.log(chat);
return (
<Layout>
<Sider>Sider</Sider>
<Layout className={styles.chatContent}>
<ChatHeader />
<Form initialValues={{ ...chat }} name="chat" onValuesChange={onChange} onFinish={onSend}>
<Item name="firstInput">
<ChatFirstContent />
</Item>
<ChatFooter />
</Form>
</Layout>
</Layout>
);
};
export default Chat;
import { PageContainer } from '@ant-design/pro-components';
import { Alert, Card, Typography } from 'antd';
import { Alert, Card, Typography, Layout } from 'antd';
import React from 'react';
import { FormattedMessage, useIntl } from 'umi';
import styles from './Welcome.less';
const CodePreview: React.FC = ({ children }) => (
<pre className={styles.pre}>
<code>
<Typography.Text copyable>{children}</Typography.Text>
</code>
</pre>
);
const { Content } = Layout;
const Welcome: React.FC = () => {
const intl = useIntl();
return (
<PageContainer>
<Card>
<Alert
message={intl.formatMessage({
id: 'pages.welcome.alertMessage',
defaultMessage: 'Faster and stronger heavy-duty components have been released.',
})}
type="success"
showIcon
banner
style={{
margin: -12,
marginBottom: 24,
}}
/>
<Typography.Text strong>
<a
href="https://procomponents.ant.design/components/table"
rel="noopener noreferrer"
target="__blank"
>
<FormattedMessage id="pages.welcome.link" defaultMessage="Welcome" />
</a>
</Typography.Text>
<CodePreview>yarn add @ant-design/pro-components</CodePreview>
</Card>
</PageContainer>
<Layout>
<Content>111</Content>
</Layout>
);
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment