Commit 08c351f4 authored by littleforest's avatar littleforest

feat: add chat of the molibe version

parent 4ce8dd4a
...@@ -23,8 +23,8 @@ ...@@ -23,8 +23,8 @@
"prepare": "husky install", "prepare": "husky install",
"prettier": "prettier -c --write \"src/**/*\"", "prettier": "prettier -c --write \"src/**/*\"",
"serve": "umi-serve", "serve": "umi-serve",
"start": "cross-env UMI_ENV=dev umi dev", "start": "SET NODE_OPTIONS=--openssl-legacy-provider && cross-env UMI_ENV=dev umi dev",
"start:dev": "cross-env REACT_APP_ENV=dev MOCK=none UMI_ENV=dev umi dev", "start:dev": "SET NODE_OPTIONS=--openssl-legacy-provider && cross-env REACT_APP_ENV=dev MOCK=none UMI_ENV=dev umi dev",
"start:no-mock": "cross-env MOCK=none UMI_ENV=dev umi dev", "start:no-mock": "cross-env MOCK=none UMI_ENV=dev umi dev",
"start:no-ui": "cross-env UMI_UI=none UMI_ENV=dev umi dev", "start:no-ui": "cross-env UMI_UI=none UMI_ENV=dev umi dev",
"start:pre": "cross-env REACT_APP_ENV=pre UMI_ENV=dev umi dev", "start:pre": "cross-env REACT_APP_ENV=pre UMI_ENV=dev umi dev",
...@@ -100,4 +100,4 @@ ...@@ -100,4 +100,4 @@
"engines": { "engines": {
"node": ">=12.0.0" "node": ">=12.0.0"
} }
} }
\ No newline at end of file
.content { .cardPadding {
width: 100%; padding: 8px;
padding: 100px; }
background: white; .CardContent {
.cardPadding { display: flex;
margin: 16px 18px; flex-wrap: wrap;
} justify-content: center;
.CardContent { margin-bottom: 150px;
display: flex;
flex-wrap: wrap;
justify-content: center;
}
} }
import { Layout } from 'antd'; import { Row, Col } from 'antd';
import type { FC } from 'react'; import type { FC } from 'react';
import { FormattedMessage, useIntl } from 'umi';
import styles from './content.less'; import styles from './content.less';
import ProductionCard from './productionCard'; import ProductionCard from './productionCard';
import ChatHeader from './header';
const { Content } = Layout;
interface ChatFirstContentProps { interface ChatFirstContentProps {
onChange?: (text: string) => void; onChange?: (text: string) => void;
...@@ -75,17 +71,19 @@ const ChatFirstContent: FC<ChatFirstContentProps> = (props) => { ...@@ -75,17 +71,19 @@ const ChatFirstContent: FC<ChatFirstContentProps> = (props) => {
]; ];
return ( return (
<Content className={styles.content}> <div className={styles.CardContent}>
<div className={styles.CardContent}> <Row gutter={1}>
{cardList.map((item, index) => { {cardList.map((item, index) => {
return ( return (
<div className={styles.cardPadding} key={`${item.title}-card-${index}`}> <Col lg={8} md={12} span={8} xs={16} sm={16} key={`${item.title}-card-${index}`}>
<ProductionCard title={item.title} content={item.content} onChange={item.onclick} /> <div className={styles.cardPadding}>
</div> <ProductionCard title={item.title} content={item.content} onChange={item.onclick} />
</div>
</Col>
); );
})} })}
</div> </Row>
</Content> </div>
); );
}; };
......
.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;
...@@ -3,23 +3,43 @@ ...@@ -3,23 +3,43 @@
.chatContent { .chatContent {
background: white !important; background: white !important;
} }
.sider { .siderWrapper {
width: 240px !important; background: white;
min-height: 100vh; .sider {
padding: 30px 20px; position: fixed;
.siderChatContent { left: 0;
height: 70%; z-index: 100;
:global(.ant-btn-primary) { width: 240px;
background: #009b95; min-height: 100vh;
border: solid 1px #009b95; padding: 30px 20px;
border-radius: 2px; background-color: #001529;
.siderChatContent {
height: 70%;
min-height: 400px;
:global(.ant-btn-primary) {
background: #009b95;
border: solid 1px #009b95;
border-radius: 2px;
}
}
.siderTabs {
}
.noMentionLogin {
} }
} }
.siderTabs { }
} .header {
.noMentionLogin { margin-top: 68px;
color: #333;
font-size: 32px;
line-height: 45px;
text-align: center;
.subTitle {
color: #999999;
font-weight: 400;
} }
} }
.chatSiderChatTabsCard { .chatSiderChatTabsCard {
display: flex; display: flex;
margin-top: 40px; margin-top: 40px;
...@@ -50,3 +70,42 @@ ...@@ -50,3 +70,42 @@
font-family: PingFangSC-Regular, PingFang SC; font-family: PingFangSC-Regular, PingFang SC;
} }
} }
.footer {
position: fixed;
bottom: 0;
width: calc(100% - 200px);
height: 150px;
padding: 16px;
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;
}
}
}
.mobileHeader {
height: 44px;
color: white;
font-size: 15px;
background-color: #009b95;
}
/* eslint-disable @typescript-eslint/no-unused-expressions */ /* eslint-disable @typescript-eslint/no-unused-expressions */
import { Layout, Form, Button } from 'antd'; import { Form, Button, Col, Row, Input, Typography } from 'antd';
import React, { useState } from 'react'; import React, { useState } from 'react';
import styles from './index.less'; import styles from './index.less';
import ChatFirstContent from './components/content'; import ChatFirstContent from './components/content';
import ChatHeader from './components/header';
import ChatFooter from './components/footer';
import { import {
DeleteOutlined, DeleteOutlined,
FieldTimeOutlined,
MenuOutlined,
PlusOutlined, PlusOutlined,
SettingOutlined, SettingOutlined,
UserOutlined, UserOutlined,
WechatOutlined, WechatOutlined,
} from '@ant-design/icons'; } from '@ant-design/icons';
import classNames from 'classnames'; import classNames from 'classnames';
import { Grid } from 'antd';
const { useBreakpoint } = Grid;
const { Title } = Typography;
const { Sider } = Layout;
const { Item } = Form; const { Item } = Form;
const Chat: React.FC = () => { const Chat: React.FC = () => {
const screens = useBreakpoint();
const isMobile = screens.xs;
const [chat, SetChat] = useState({ const [chat, SetChat] = useState({
chatInput: '', chatInput: '',
}); });
const [showSider, setShowSider] = useState(true);
const [firstChat, setFirstChat] = useState(false); const [firstChat, setFirstChat] = useState(false);
const [form] = Form.useForm(); const [form] = Form.useForm();
const [selectSiderTabs, setSelectSiderTabs] = useState(''); const [selectSiderTabs, setSelectSiderTabs] = useState('');
...@@ -68,66 +75,135 @@ const Chat: React.FC = () => { ...@@ -68,66 +75,135 @@ const Chat: React.FC = () => {
setSelectSiderTabs(value); setSelectSiderTabs(value);
}; };
const renderMobileHeader = () => {
return (
<Row align={'middle'} justify="space-between" gutter={1} className={styles.mobileHeader}>
<Col push={1}>
<MenuOutlined
onClick={() => {
setShowSider(!showSider);
}}
/>
</Col>
<Col>AI改变世界</Col>
<Col pull={1}>
<FieldTimeOutlined />
</Col>
</Row>
);
};
return ( return (
<Layout> <>
<Sider className={styles.sider}> {isMobile && renderMobileHeader()}
<div className={styles.siderChatContent}> <Row>
<Button size="large" block type="primary" icon={<PlusOutlined />}> {showSider && (
新建对话 <Col span={4} sm={10} md={7} xs={12} lg={5} className={styles.siderWrapper}>
</Button> <div className={styles.sider}>
</div> <div className={styles.siderChatContent}>
<div className={styles.siderTabs}> <Button size="large" block type="primary" icon={<PlusOutlined />}>
{siderTabsList.map((item) => { 新建对话
return ( </Button>
<div
key={item.text}
className={styles.chatSiderChatTabsCard}
onClick={() => {
selectSliderTabsHandleClick(item.checked);
}}
>
<div
className={classNames(
styles.chatSiderChatTabsCardIcons,
selectSiderTabs === item.checked && styles.checkedChatSiderChatTabsCardIcons,
)}
>
{item.icons}
</div>
<div
className={classNames(
styles.chatSiderChatTabsCardText,
selectSiderTabs === item.checked && styles.checkedChatSiderChatTabsCardText,
)}
>
{item.text}
</div>
</div> </div>
); <div className={styles.siderTabs}>
})} <Row>
</div> {siderTabsList.map((item) => {
<div className={styles.noMentionLogin} /> return (
</Sider> <Col key={item.text}>
<Layout className={styles.chatContent}> <div
{!firstChat && <ChatHeader />} className={styles.chatSiderChatTabsCard}
<Form onClick={() => {
form={form} selectSliderTabsHandleClick(item.checked);
initialValues={{ ...chat }} }}
name="chat" >
onValuesChange={onChange} <div
onFinish={onSend} className={classNames(
> styles.chatSiderChatTabsCardIcons,
{firstChat ? ( selectSiderTabs === item.checked &&
<div className={styles.chatRoom}>sss</div> styles.checkedChatSiderChatTabsCardIcons,
) : ( )}
<Item name="firstInput"> >
<ChatFirstContent /> {item.icons}
</Item> </div>
<div
className={classNames(
styles.chatSiderChatTabsCardText,
selectSiderTabs === item.checked &&
styles.checkedChatSiderChatTabsCardText,
)}
>
{item.text}
</div>
</div>
</Col>
);
})}
</Row>
</div>
<div className={styles.noMentionLogin} />
</div>
</Col>
)}
<Col className={styles.chatContent} span={20} lg={19} sm={14} md={17} xs={12}>
{!firstChat && (
<>
<div className={styles.header}>
<Row>
<Col span={24}>
<Title level={1}>产品名称</Title>
</Col>
<Col span={24}>
<Title level={5} className={styles.subTitle}>
AI改变世界
</Title>
</Col>
</Row>
</div>
</>
)} )}
<ChatFooter />
</Form> <Form
</Layout> form={form}
</Layout> initialValues={{ ...chat }}
name="chat"
onValuesChange={onChange}
onFinish={onSend}
>
{firstChat ? (
<div className={styles.chatRoom}>sss</div>
) : (
<Item name="firstInput">
<ChatFirstContent />
</Item>
)}
<div className={styles.footer}>
<Row>
<Col span={20}>
<div className={styles.chatWrapper}>
<Item name="chatInput">
<Input
placeholder="在这里输入你想知道的问题,给我几句提示,我来帮你回答"
size="large"
/>
</Item>
</div>
</Col>
<Col span={4}>
<div className={styles.outputButtonWrapper}>
<Item name="outputButton">
<Button type="primary" size="large">
发送
</Button>
</Item>
</div>
</Col>
</Row>
</div>
</Form>
</Col>
</Row>
</>
); );
}; };
......
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